Since all of my open source projects are turning to HTML-5/JS based architectures, I started looking into platforms to develop stamp-webservices 4.0 that would be on the NodeJS platform. I am also supporting ng-scrolling-table which is AngularJS based. I had previously used Netbeans 8.0.X for developing ng-scrolling-table, however the lack of NodeJS debugging and support for many of the NodeJS capabilities was forcing me to look elsewhere. I tried Eclipse again, but like usual with Eclipse, it either works great or not at all. For me it was the later. I had been using MS Visual Studio 2013 however I found this platform rather "annoying" (to say the least - lots of odd key sequences, scrolling in the files and slower than I'd like for pure JS tools).
This led me to look at Webstorm. I had always avoided it, because it seems like just one more IDE tool, was a commercial product and I wanted to support Netbeans/Eclipse initiatives. But after one evening of using the trial version I was impressed! Not only was I able to do full HTML-5 debugging in it, I was able to launch my NodeJS server, debug content, it recognized when node was running and asked to restart (when switching between run and debug modes) and was able to executer all of my Mocha integration tests from the IDE with full stack trace link through. I was sold. I also noticed that they offer a program to support Open Source projects (both of these are) and provide a free license key to the projects. Superb, and I may not consider discussing with my manager to obtain a license for work related activities. Nice to see a company supporting the open source community (which all these companies use internally)
Monday, October 20, 2014
Wednesday, August 27, 2014
Playing flac files in Windows Media Player (WMP)
If you are like me, you don't have a lot of tools for playing video and music files. You use a few simple tools and keep in simple. In my case I primarily use WMP (Windows Media Player) on Windows 8.X and sometimes VLC Player, (esp. on my Linux systems).
If you try and play .flac files in WMP they will not play because the codec is not available. No worries, as there is a great project I found hosted on xiph.org that provides these files to the Windows environment.
If you try and play .flac files in WMP they will not play because the codec is not available. No worries, as there is a great project I found hosted on xiph.org that provides these files to the Windows environment.
Labels:
WMP
Saturday, October 12, 2013
Writing Selenium Tests in a more DSL like way
I noted in a previous blog post that I was starting to write more tests in a more fluent DSL like manner. I thought I would illustrate this. Here is an example of a test that does the following (assuming you are logged in on the home screen):
On thing to point out is that when I call a method like
As mentioned earlier, I am using an attribute factory to get the attribute. An attribute is a nifty class I created which is able to hold a value that was set (so I can verify it) and also state what the input type is (selection, checkbox, text etc.) and is able to return a selenium
On large disadvantage of using the chaining approach is exceptions. Unless your methods themselves do not report errors well, it is difficult to trace what line causes the error. This is one disadvantage of DSL interfaces and means you need to think better about the erroneous conditions and how best to log/print them to console/log files.
- From the navigator (think of it as a button bar) click the "Create wantlist" - this will launch a create wantlist editor and return this solvent.
- We want to fill in the fields and check for certain conditions (like if the form is valid or not).
- We want to hit "save" button
public void create() { Navigation nav = new Navigation(config); WantlistEditor editor = nav.create(Navigation.CreateAction.WANTLIST); String id = generateUnique(""); editor.invalid() .set(factory.get(StampAttribute.Country, Country.BASUTOLAND)) .set(factory.get(StampAttribute.Denomination, "2d")) .set(factory.get(StampAttribute.Description, "scarlet (\"Tail\" flaw)")) .set(factory.get(StampAttribute.Catalogue, Catalogue.STANLEY_GIBBONS)) .set(factory.get(StampAttribute.CatalogueCondition, Condition.MINT_NG)) .set(factory.get(StampAttribute.CatalogueNumber, "193a-" + id)) .set(factory.get(StampAttribute.CatalogueValue, 2.25)) .valid() .save() .success();
On thing to point out is that when I call a method like
valid() or invalid() I am not returning a boolean from the function (in the past it would have been a isValid() type syntax. Instead, I am coding the test as I expect it to behave and if it is not behaving in this manner it will fail at that point. As well a method like success() is programmed to look for the closure of the editor as marking a successful create.As mentioned earlier, I am using an attribute factory to get the attribute. An attribute is a nifty class I created which is able to hold a value that was set (so I can verify it) and also state what the input type is (selection, checkbox, text etc.) and is able to return a selenium
By object that I can use for selection. On large disadvantage of using the chaining approach is exceptions. Unless your methods themselves do not report errors well, it is difficult to trace what line causes the error. This is one disadvantage of DSL interfaces and means you need to think better about the erroneous conditions and how best to log/print them to console/log files.
Selecting ChosenJS values with Selenium
I had previously blogged about selection of GXT selections with selenium and figured it might be worthwhile if I posted what I was doing with my new AngularJS app that is using ChosenJS as my selection of choice (I wrapped this in a simple directive)
For my selenium tests, I try and write most of the code in DSL format in a object termed a Solvent. We use this term at my place of employment and I think it is a good term and have continued to use it. This allows me to encapsulate the underlying implementation while presenting a functional level to the selenium tests. For form controls, I use a generic Attribute class that along with an AttributeHandler knows how to process any attribute type (for example, checkboxes, textfields, textareas, selections, date pickets etc.). Thus we come to the "code" of how I handle ChosenJS Selections.
First off, lets look at what the generated HTML looks like for the AngularJS control (this represents a drop-down for my stamp conditions):
Mostly this is Angular, although you may notice the
If ChosenJS was not present we could simply operate on this HTML and use an element selector like
And it is this fragment that we need to interact with (since the
In the code fragment above, the parent is passed to the AttributeHandler as a WebElement. This is the container where that form element is located. It could be a fieldset, a panel div or a popup window etc. It is just a starting point so I can find the appropriate element in close proximity. The ngWait( ) method comes from the Protractor project (obviously it is a Java version of this) and simply waits for Angular to complete its digest (The fluent angular project uses this and you can see the source here.)
You may also notice I do an assertion check just to ensure that the value got set on the link. I may ultimately remove this.
But wait, I see you are using xpaths.... that is so last year.... You are right. CSS Selectors is definitely a better way to go. Except.... there is no CSS selector for parent. Often I have found I am starting to use a more mix of CSS Selectors and XPaths. I suppose I could have gotten a Web Element for the
I have been a little slow putting together a regression suite in Selenium for my redesigned Stamp Web application written in AngularJS, but I want to upgrade to 1.2.0 and in order to do so wanted to have about 15-20 critical test cases covered first. So far my experiences has been very positive and the number of timing issues is almost negligible (the only issue I have had is when I launch the application I maximize it and sometimes the app will start the login before maximized which causes some issues). Other than that, I have yet to have to use a single "
For my selenium tests, I try and write most of the code in DSL format in a object termed a Solvent. We use this term at my place of employment and I think it is a good term and have continued to use it. This allows me to encapsulate the underlying implementation while presenting a functional level to the selenium tests. For form controls, I use a generic Attribute class that along with an AttributeHandler knows how to process any attribute type (for example, checkboxes, textfields, textareas, selections, date pickets etc.). Thus we come to the "code" of how I handle ChosenJS Selections.
First off, lets look at what the generated HTML looks like for the AngularJS control (this represents a drop-down for my stamp conditions):
<select class="condition-selector ng-pristine ng-valid ng-valid-required" name="condition" data-jq-chosen data-options="conditions" data-placeholder="Select a condition" data-ng-model="model.activeCatalogueNumber.condition" data-ng-required="true" data-ng-change="validate()" tabindex="-1" required="required" style="display: none;"> <option value="? string:0 ?"></option> <!-- ngRepeat: cond in conditions --> <option data-ng-repeat="cond in conditions" value="0" class="ng-scope ng-binding">Mint</option> <option data-ng-repeat="cond in conditions" value="1" class="ng-scope ng-binding">Mint (NH)</option> <option data-ng-repeat="cond in conditions" value="2" class="ng-scope ng-binding">Used</option> <option data-ng-repeat="cond in conditions" value="3" class="ng-scope ng-binding">Cancel to Order</option> <option data-ng-repeat="cond in conditions" value="4" class="ng-scope ng-binding">Mint No Gum</option> </select>
Mostly this is Angular, although you may notice the
data-jq-chosen and data-options variables which are instructions/directives for my directive (one indicates it should turn this drop-down into a ChosenJS control and the other that it should watch/bind to the conditions variable on the controller). If you are not using AngularJS this probably doesn't mean to much to you.If ChosenJS was not present we could simply operate on this HTML and use an element selector like
By.ByName("condition-selector") and click it and choose the appropriate <option> tag matching the value desired. But when ChosenJS is present, it will add additional HTML into the DOM. Specifically for the above example we have this:<div class="chosen-container chosen-container-single chosen-container-single-nosearch" style="width: 121px;" title=""> <a class="chosen-single chosen-single-with-deselect" tabindex="-1"><span>Mint</span><abbr class="search-choice-close"></abbr></a> <div class="chosen-drop"> <div class="chosen-search"><input type="text" autocomplete="off" readonly="" tabindex="21"></div> <ul class="chosen-results"> <li class="active-result result-selected ng-scope ng-binding" data-option-array-index="1" style="">Mint</li> <li class="active-result ng-scope ng-binding" data-option-array-index="2" style="">Mint (NH)</li> <li class="active-result ng-scope ng-binding" data-option-array-index="3" style="">Used</li> <li class="active-result ng-scope ng-binding" data-option-array-index="4" style="">Cancel to Order</li> <li class="active-result ng-scope ng-binding" data-option-array-index="5" style="">Mint No Gum</li> </ul> </div> </div>
And it is this fragment that we need to interact with (since the
chosen-container floats on top of the select DOM element). This ChosenJS DOM will always appear as a peer to the select DOM elements. I order to get this to work in Selenium we need to:- Click the
chosen-containerto invoke the drop-down (this is unpopulated until shown for performance reasons) - Click the appropriate
lielement.
case Select: elm = parent.findElement(attr.asBy()); String chosen = "../div[contains(@class,'chosen-container')]"; elm.findElement(SolventHelper.ngWait(By.xpath(chosen + "/a"))).click(); elm.findElement(SolventHelper.ngWait(By.xpath(chosen + "/div[contains(@class,'chosen-drop')]/ul/li[.=\"" + attr.getValue() + "\"]"))).click(); assertEquals(attr.getValue(), elm.findElement(SolventHelper.ngWait(By.xpath(chosen + "/a"))).getText()); break;
In the code fragment above, the parent is passed to the AttributeHandler as a WebElement. This is the container where that form element is located. It could be a fieldset, a panel div or a popup window etc. It is just a starting point so I can find the appropriate element in close proximity. The ngWait( ) method comes from the Protractor project (obviously it is a Java version of this) and simply waits for Angular to complete its digest (The fluent angular project uses this and you can see the source here.)
You may also notice I do an assertion check just to ensure that the value got set on the link. I may ultimately remove this.
But wait, I see you are using xpaths.... that is so last year.... You are right. CSS Selectors is definitely a better way to go. Except.... there is no CSS selector for parent. Often I have found I am starting to use a more mix of CSS Selectors and XPaths. I suppose I could have gotten a Web Element for the
"chosen" variable and then simply used CSS selectors from that. Overall, what is nice about this, is I have yet to run into a problem with timing issues like I had with GXT and EXT-JS selectors. Also, the li tags for the values will be ALL the values in a scrollable window, so selenium will select the right value even if it is not on the screen.I have been a little slow putting together a regression suite in Selenium for my redesigned Stamp Web application written in AngularJS, but I want to upgrade to 1.2.0 and in order to do so wanted to have about 15-20 critical test cases covered first. So far my experiences has been very positive and the number of timing issues is almost negligible (the only issue I have had is when I launch the application I maximize it and sometimes the app will start the login before maximized which causes some issues). Other than that, I have yet to have to use a single "
pause()" method which is really nice.Thursday, October 3, 2013
Arquillian with Glassfish 4 - early trials
With the release of Glassfish 4 and J2EE version 7, I decided to work at upgrading my stamp web services application to the platform. An important part of my project is my 580 odd tests that include approximately 300 or so Arquillian tests. Since my application takes advantage of Container Managed transaction context and persistence providers, it is not sufficient for me to simply tests these in a out-of-container context. Afterall, how can I verify that listeners or cascading relationships cleanup correctly on a delete operation preventing orphans?
In making the shift to Glassfish 4, I also upgraded the version of Arquillian and ShrinkWrap I was using and ran into essentially classpath hell. I figured my adventures were sufficient that I would blog about it.
First off, once I had it all working, I ran into a bug under Arquillian 1.1.1.Final. The exception was
It turns out, there is an existing bug for this: . In order to workaround this bug, I needed to use Arquillian 1.0.3.Final. Hopefully this will get fixed soon and I can move up.
So moving to what I changed (that is why you came here right?) lets start with the pom.xml.
I would provide the full pom.xml, but it is quite large (currently 508 lines) so I only included these snippets (also pygments.org is not up so I can not get nicely formatted code) .
Overall, this was a little more painful than I expected - although most of the pain came in the changes to ShrinkWrap and Arquillian versions that I thought I needed for GF4. What compounded this was the sneaky inappropriate version of CDI that was causing all the dependency injection to fail.
Problem with Latest Arquillian
In making the shift to Glassfish 4, I also upgraded the version of Arquillian and ShrinkWrap I was using and ran into essentially classpath hell. I figured my adventures were sufficient that I would blog about it.
First off, once I had it all working, I ran into a bug under Arquillian 1.1.1.Final. The exception was
WELD-001456 Argument resolvedBean must not be null
It turns out, there is an existing bug for this: . In order to workaround this bug, I needed to use Arquillian 1.0.3.Final. Hopefully this will get fixed soon and I can move up.
Updates to pom.xml
So moving to what I changed (that is why you came here right?) lets start with the pom.xml.
- Since J2EE 7 uses a pretty recent version of Jersey for JAX-RS compliance, I modified my included Jersey dependencies from compile to provided. (The exception was jersey-client used in my tests that I might not need anymore with the latest JSR specs). I tied the version to the version in Glassfish 4 for compatibility (1.17)
- I didn't think I would need eclipselink when testing with the embedded glassfish, but this turned out to be needed. So for this I used the 2.5.0 version matching Glassfish 4. As well, since I do not have a compile time dependency I changed the scope from provided to runtime.
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>${eclipselink.version}</version>
<exclusions>
<exclusion>
<artifactId>commonj.sdo</artifactId>
<groupId>commonj.sdo</groupId>
</exclusion>
</exclusions>
<scope>runtime</scope>
</dependency>
- I was previously including the dependency
org.eclipse.persistence.moxyto support MOXy in my application, but since this is the default provider now for Glassfish 4 JAXB processing (for JSON) I was able to remove it.
- For the
glassfish-embedded-allartifact, I switched to use 4.0.
- Finally, in the surefire-plugin configuration, I had some classpath dependency exclusions. I had to add CDI to this or else Arquillian was bombing out (one of the JARs was bringing in a incompatible version of cdi-api). I found this using the netbeans maven plugin and the graphical display and this really helps. For reference here is the exclusions:
<classpathDependencyExcludes> <classpathDependencyExcludes>javax.servlet:servlet-api</classpathDependencyExcludes> <classpathDependencyExcludes>org.apache.felix:javax.servlet</classpathDependencyExcludes> <classpathDependencyExcludes>javax:javaee-web-api</classpathDependencyExcludes> <classpathDependencyExcludes>javax.enterprise:cdi-api</classpathDependencyExcludes> <classpathDependencyExcludes>org.jboss.spec:jboss-javaee-web-6.0</classpathDependencyExcludes> </classpathDependencyExcludes> - Updated the version of ShrinkWrap to 2.0.0
I would provide the full pom.xml, but it is quite large (currently 508 lines) so I only included these snippets (also pygments.org is not up so I can not get nicely formatted code) .
Summary
Overall, this was a little more painful than I expected - although most of the pain came in the changes to ShrinkWrap and Arquillian versions that I thought I needed for GF4. What compounded this was the sneaky inappropriate version of CDI that was causing all the dependency injection to fail.
Labels:
Arquillian,
EclipseLink,
Glassfish,
GS4
Friday, November 9, 2012
J2EE Application with MOXy
As part of my refactoring of my existing J2EE application using JAX-RS, I wanted to try and reduce the JAXB custom code in place. Previously I was using Jackson and Jersey for JSON serialization using the "Mapped" notation. This involved creating my own JAXBContext object and I was required to create some special mapping processing so that I could map an attribute as etiher an array, non-string or other value.
Since I was going to use the latest version of eclipselink with the refactoring (currently EclipseLink 2.4.1) I decided to check out using MOXy which I had always had my eye on. My goal was to avoid the mapping approach (which was inherently buggy since it required me to remember to add any field to a property file for proper serialization and I could not serialize the same named field differently for different types - ie. field X was always to be type Y). MOXy seemed to like it might be able to address these concerns.
To leverage MOXy in your environment, you need to include it as a provider. In my case I included it in my JAX-RS Application class and set some configuration properties on it. Here is an example of my current application (note I am using Package scanning for JAX-RS resources/providers in Jersey)
You can read more on the MOXy settings here.
You then need to reference your Application in your
There are other ways to configure the MOXy configuration, but this is the one that I choose and seemed to fit well for my environment (since I was using a
Since several of my JPA entities included a foreign reference to another JPA entity, I wanted only the ID of the foreign entity to be serialized. Previously I had been using the
In the
I am having a small issue with arrays of Entities. I have a serializable class which is Genericized and has two fields:
The resulting JSON will thus look as I intended:
Not sure what I am missing here, but I need to address this at some point along with modifying my entity IDs from wrapper types to primitives.
Since I was going to use the latest version of eclipselink with the refactoring (currently EclipseLink 2.4.1) I decided to check out using MOXy which I had always had my eye on. My goal was to avoid the mapping approach (which was inherently buggy since it required me to remember to add any field to a property file for proper serialization and I could not serialize the same named field differently for different types - ie. field X was always to be type Y). MOXy seemed to like it might be able to address these concerns.
To leverage MOXy in your environment, you need to include it as a provider. In my case I included it in my JAX-RS Application class and set some configuration properties on it. Here is an example of my current application (note I am using Package scanning for JAX-RS resources/providers in Jersey)
public class WebApplication extends PackagesResourceConfig { @SuppressWarnings("unused") private static final Logger logger = Logger.getLogger(WebApplication.class.getName()); public WebApplication() { super("org.javad.web.providers","org.javad.preferences.model.resources","org.javad.stamp.model.resources"); } @Override public Set<Object> getSingletons() { MOXyJsonProvider moxyJsonProvider = new MOXyJsonProvider(); moxyJsonProvider.setAttributePrefix(""); moxyJsonProvider.setFormattedOutput(true); moxyJsonProvider.setIncludeRoot(false); moxyJsonProvider.setMarshalEmptyCollections(true); moxyJsonProvider.setValueWrapper("$"); Set<Object> set = new HashSet<Object>(); set.add(moxyJsonProvider); return set; } }
You then need to reference your Application in your
web.xml as part of your JAX-RS resource mapping:<init-param> <param-name>javax.ws.rs.Application</param-name> <param-value>org.javad.web.WebApplication</param-value> </init-param>
PackageResourceConfig from Jersey for finding my resources).Since several of my JPA entities included a foreign reference to another JPA entity, I wanted only the ID of the foreign entity to be serialized. Previously I had been using the
@XmlIDRef to drive this for serialization, but I had difficulty using this with MOXy. Instead, I needed to declare an XML Adapter to do the serialization and deserialization of the field. This is done using the @XmlJavaTypeAdapter annotation. For my album entity, the foreign key reference to the stamp collection entity looks like this:@XmlJavaTypeAdapter(StampCollectionRefAdapter.class) @XmlElement(name = StampFormConstants.STAMP_COLLECTION_REF ) @ManyToOne(optional=false,fetch=FetchType.EAGER) @JoinColumn(name="COLLECTION_ID",nullable=false) private StampCollection collection;
StampCollectionRefAdapter I transfer the StampCollection entity to an ID and vice versa (when deserializing from a JSON posting). One issue I ran into was that I could not inject the StampCollectionService into this class. This is because these classes are initialized by MOXy (it would appear) prior to the CDI and EntityManagerFactory initialization, so I needed to obtain the EntityManagerFactory which was used in my initialization servlet listener (this sets up a few configurations in my environment). I had tried declaring this class as a @Stateless EJB but did not have any luck (likely because it was constructed explicitly). I may look into this further later, but for now the only way I could get access to the service to transfer the ID back to the physical entity was to leveage the entity manager factory from the initialization listener through a static context (note: this would might fail if I tried to perform any transactions in against this, but should work for normal queries)public class StampCollectionRefAdapter extends XmlAdapter<StampCollectionRefAdapter.StampCollectionRefType, StampCollection> { public StampCollectionRefAdapter() { super(); } @Override public StampCollection unmarshal(StampCollectionRefType v) throws Exception { StampCollection collection = null; EntityManagerFactory emf = SessionInitializer.getEntityManagerFactory(); if( emf != null ) { EntityManager em = emf.createEntityManager(); if( em != null ) { collection = em.find(StampCollection.class, v.id); } } return collection; } @Override public StampCollectionRefType marshal(StampCollection v) throws Exception { StampCollectionRefType t = new StampCollectionRefType(); t.id = v.getId().longValue(); return t; } public static class StampCollectionRefType { @XmlValue public long id; } }
I am having a small issue with arrays of Entities. I have a serializable class which is Genericized and has two fields:
- total - representing the total number of objects (not necessarily the items returned)
- items - the List
of entities to be returned
getItems() method on the abstract class. Instead I had to declare it on the concrete class that implements the Generic type. The reason for this is I want my array of items to be the plural of the actual items contained within it. This requires me to declare the collection similiar to the following:@XmlRootElement(name="list") @XmlAccessorType(XmlAccessType.PROPERTY) public class AlbumModelList extends AbstractModelList<Album> { @Override @XmlElement(name="albums") public List<Album> getItems() { return items; } }
{
"total": 5,
"albums": [
{
"id": "2000",
"name": "Test Collection X",
"countryRefs": [],
"stampCollectionRef": 1
},
{
"id": "1",
"name": "Test Collection x2",
"countryRefs": [],
"stampCollectionRef": 1
},
{
"id": "2",
"name": "Test Collection x4",
"countryRefs": [],
"stampCollectionRef": 1
},
{
"id": "3",
"name": "Test Collection x5",
"countryRefs": [],
"stampCollectionRef": 1
},
{
"id": "4",
"name": "Test Collection x6",
"countryRefs": [],
"stampCollectionRef": 1
}
]
}
But if I use a content type of XML (which I am not using very often) the Array is not showing up as am <albums/> element that contains <album/> nodes but instead looks like the following:<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <list> <total>5</total> <albums id="2000"> <name>Test Collection X</name> <stampCollectionRef>1</stampCollectionRef> </albums> <albums id="1"> <name>Test Collection x2</name> <stampCollectionRef>1</stampCollectionRef> </albums> <albums id="2"> <name>Test Collection x4</name> <stampCollectionRef>1</stampCollectionRef> </albums> <albums id="3"> <name>Test Collection x5</name> <stampCollectionRef>1</stampCollectionRef> </albums> <albums id="4"> <name>Test Collection x6</name> <stampCollectionRef>1</stampCollectionRef> </albums> </list>
Not sure what I am missing here, but I need to address this at some point along with modifying my entity IDs from wrapper types to primitives.
Labels:
EclipseLink,
JAX-RS,
JSON,
MOXy
EclipseLink logging with Arquillian in Eclipse
I have been doing some experimentation with Arquillian for testing my refactored J2EE application in embedded glassfish. I really like it so far, but I ran into an issue where me
to no avail. I also set this value to
This allows me to see the SQL statements (assuming your set the other log values) in both Eclipse and through the maven command line test execution.
test-persistence.xml file use did not see to provide anything more than SERVERE level logging from eclipselink. I had tried setting the property <property name="eclipselink.logging.logger" value="DefaultLogger"/>
to no avail. I also set this value to
JavaLogger without results. I finally stumbled across an answer while looking into changing the embedded glassfish http port - and that is to use the following value:<property name="eclipselink.logging.logger" value="org.eclipse.persistence.logging.DefaultSessionLog"/>
This allows me to see the SQL statements (assuming your set the other log values) in both Eclipse and through the maven command line test execution.
Labels:
Arquillian,
Eclipse,
EclipseLink
Thursday, November 1, 2012
Diving into J2EE6 with JTA
I have been silent for a long time on the blog (I have been busy - never fear) but simply have not spent the time here to document my activities.
I was in the process of doing a major overhaul on my server-side JAX-RS WEB Services and their accompanying persistence services to bring things up to a little more standard approach. In particular my goals were to:
As you can imagine this has turned out not to be a small effort and I have had to learn and re-learn a lot of areas of J2EE I had convienently left behind in my memory space.
The following is probably the most important points to remember when designing an application like this:
Along with my services, I am actually going to rewrite my client side application from a GWT/GXT 2 based solution to SmartClient JS. I originally was going to convert to GXT 3, but I have become pretty disillusioned with the roadmap from Sencha, and therefore are planning to go with a JS based client application. In order to pace this, I need to keep the existing GXT 2 + WEB Services running (which is why I am creating a new Web application project) and will be converting/creating client portions on a priority basis. As well, from the services perspective I am attempting to capture a new level of test code coverage (before it was about 45% now I am aiming for 70%+). To accomplish this, I am not writign any WEB Services beyond my first one to ferret out the testing/WADL approaches to prevent me from working on the client code until the server is complete and solid.
I was in the process of doing a major overhaul on my server-side JAX-RS WEB Services and their accompanying persistence services to bring things up to a little more standard approach. In particular my goals were to:
- Utilize more dependency injection (from JSR-299) to avoid having to separately manage my services in a factory.
- Utilize JPA using the JTA transactions and a JDBC datasource (I was previously using
Resource_Localtransaction modes - Inject the EntityManager (or factory - see below)
- Leverage in-container testing using Arquillian for the services (to verify the transactional integrity of the services)
- Clear out remnants and methods from when the services were used by a Swing Application (which was replaced by Stamp Web 1.0 in 2008)
- Leverage MOXy with JAXB for JSON serialization from JAX-RS WEB Services in place o the Jersey implementation with Jackson and mapped notation (which had required me to create custom JABXContext objects, register properties in my custom mapping file etc.)
- Provide a proper JAX-RS implementation using Response Builders. Previously I was returning a JSON object with a success flag instead of using valid HTTP Status objects like NOT_FOUND (404)
- Provide complete testing of all JAX-RS WEB Service methods in particular using both JSON and XML supported content encodings and verifying all response code for non-conditions.
As you can imagine this has turned out not to be a small effort and I have had to learn and re-learn a lot of areas of J2EE I had convienently left behind in my memory space.
The following is probably the most important points to remember when designing an application like this:
- Start small. I didn't simply start modifying my codebase. Instead I started a new project and brought over the highest level concepts (in my case my PersistableObject, AbstractPersistenceService and a few other classes) and built it up from there - testing as I went. This allowed me to verify the new JTA based approach and also let me figure out a few concerns. For example, previously I had to manage all commit/rollback code. Initially I was thinking to mark methods as Transactional and write an interceptor (which led me down a deep hole of Interceptors) only to realize this was not needed in a JTA context.
- Early on I read a blog article that stated that you shouldn't use
@PersistenceContext(injecting an EntityManager) because it wasn't thread safe and should instead use@PersistenceUnit(injecting an EntityManagerFactory). This seemed like a good idea and worked... until I tried to save 150 stamps (which each created a EntityManager at a lower level of the code). It appears when using JTA and Container Managed transactions (CMT) creating an EntityManager from the factory will establish a different connection in the pool (I couldn't verify this other than I was seeing max-connection errors and deadlocks in my arquillian tests - but only when this test was used). After some reading, I saw that using@PersistenceContextin CMT it becomes the responsibility of the container to close and manage the EntityManagers. Doing so (in place of using the factory to get a new one) instantly rid me of the connection errors and I see a balance of connection threads - Note the test that hit this is one that never happens in my WEB application (yet) but I am glad to have hit this now - rather than after deploying on my production server. - Arquillian took a little effort to get completely working right, but now that I have it working it seems to work nicely for testing my services "in context". I am currently testing my WEB Services using the jersey-client module and running them after my application is deployed to glassfish. I do want to do some further experimentation to see if I can use Arquillian for these (this article looks promising: http://www.samaxes.com/2012/05/javaee-testing-introduction-arquillian-shrinkwrap/)
Along with my services, I am actually going to rewrite my client side application from a GWT/GXT 2 based solution to SmartClient JS. I originally was going to convert to GXT 3, but I have become pretty disillusioned with the roadmap from Sencha, and therefore are planning to go with a JS based client application. In order to pace this, I need to keep the existing GXT 2 + WEB Services running (which is why I am creating a new Web application project) and will be converting/creating client portions on a priority basis. As well, from the services perspective I am attempting to capture a new level of test code coverage (before it was about 45% now I am aiming for 70%+). To accomplish this, I am not writign any WEB Services beyond my first one to ferret out the testing/WADL approaches to prevent me from working on the client code until the server is complete and solid.
Labels:
EclipseLink,
JAX-RS,
JAXB,
JPA
Thursday, July 15, 2010
Firefox, Selenium GXT and the nasty Quick Find Links Only
So I have seen this intermittent error with my selenium tests that drives me up the wall. I'll be running a test and all of a sudden a little "Quick Find" box shows up in the lower left corner in Firefox (not the same as CTRL-F). This appears to be some sort of "old feature" of firefox that is used to quickly find links or something in the page (people have complained about it since Firefox 1.0). If you google the term "firefox quick find links only" you'll see the issue. Basically if you are in a non-input field (like the page) and type either "/" or "'" it will invoke this. The problem is, in GXT with selenium in order for some values to be input, events need to be raised by my selenium tests to blur/focus etc. Even though I am not typing in an apostrophe or slash, some sequence will trigger this control. Usually it was during the typing in a text field after clearing it and the first character (or in the case of my tree filter the 8th character?) would be dropped. It turns out, a solution that appears to work is the use of a Firefox plugin to turn off this widget/control (not sure why there is not a setting to do it by default - since I am sure most people do not even know the functionality is there).
There is a solution for this, but in order to use it you'll want to setup Firefox and Selenium to use a custom profile (since you have to install this plugin). To do so, start firefox with the
There is a solution for this, but in order to use it you'll want to setup Firefox and Selenium to use a custom profile (since you have to install this plugin). To do so, start firefox with the
-profileManager argument (ie. firefox -profilemanager). Be sure not to have any instances running when you do this (or else it will be ignored). When the profile manager shows up:
- uncheck the "don't ask at startup" - we'll restore this later
- choose to create a new profile
- give your profile a name like "selenium" and click the choose folder. Before going further write down this path as you will need it along with the profile name. On Windows 7, mine would be
c:\users\myusername\AppData\Roaming\Mozilla\FireFox\Profiles. - Launch Firefox using this profile.
- Go to your favorite website (like my blog). Without clicking in a textfield, hit the button "/". If you see a Quick Find show up, the next should help disable this.
- The process to disable the Quick find is documented here. In particular you'll need to download the plugin and install it to Firefox (on Windows is .xpi is not mapped to firefox choose to pick a file and choose firefox). Once installed, follow the instructions.
- After "disabling" it, try step 5 again and this time the Quick Find should not show up.
- Now you have a Firefox that will run the selenium tests without Quick Find, but selenium is not using it. The next step is to modify your selenium startup script (if you are running it by typing
java -jar selenium-server.jarwrite a script!. In the script, add the flag-firefoxProfileTemplate path_to_profile_above\profile_nameto the end of the command. This will use your custom profile for executing the tests. - Finally, close down firefox and launch it again. This time checkoff the "Don't ask at startup" and choose your regular profile and you are off back using firefox with your profile.
Friday, March 5, 2010
GXT and Selenium - Part 2
First off, to all those who have patiently asked for my solution of GXT combo boxes and selenium, I do apologize for the long time in coming. While reading my articles is certainly not like being left with a cliff hanger in a movie sequel, I know the pain in waiting anxiously for a solution.
Combo Boxes
After trying many different ways to get combo boxes to work, I have worked out a pattern which I will share which has seemed to provide the greatest stability in our tests. We currently have forty-odd selenium tests run upon check-in to trunk for the stamp webeditor project. Approximately half of them utilize one of the dozen or so combo boxes in my application and the only failures we have seen is when there is actually something wrong with our underlying code.
Version Info
GXT: 2.1.1
Selenium: 1.0.1
Combo Boxes
After trying many different ways to get combo boxes to work, I have worked out a pattern which I will share which has seemed to provide the greatest stability in our tests. We currently have forty-odd selenium tests run upon check-in to trunk for the stamp webeditor project. Approximately half of them utilize one of the dozen or so combo boxes in my application and the only failures we have seen is when there is actually something wrong with our underlying code.
Here is a break-down of the steps:
- If a label is provided (ie. a combobox with a label), attempt to wait for the combobox to be enabled. When the combobox is first shown, the backing store may be initializing or other activities may be happening, thus causing the combobox to be disabled. The routine will simply wait a duration for a given number of cycles for the combobox to be enabled.
- The combobox will be clicked.
- If the combobox results are visible, and one of those results is the item we are looking for, a
mouseDownevent will be emitted on the resulting item. If not present, a system out message will be printed (I found this useful in debugging the issue. In practice I may only see the message once if the system is bogged down and running slow) - I found a need to wait another duration after the
mouseDownevent, proceeding with firing off ablurevent. While these last may not always be needed, as I mentioned above, I have not had any failures show up due to combobox selection and having these in the code certainly have helped!
I should mention the waitDuration and waitCycles are simply integer static values (125 and 20 respectfully however I can configure these via configuration). Finally the pause() method is simply a Thread.sleep() call wrapped in a try/catch block. One of my readers Carl, suggested using the Selenium.Wait( ) functionality, which I may explore in the future.
So lets look at some code:
/** * Will select the text in a ComboBox by the specified locator. If the ComboBox is provided * a label, the method will try and determine if the ComboBox is disabled, and if it is wait * for it to become enabled (or timeout after 5000 seconds whichever is first). * * @param selenium The selenium context * @param text The text to pick from the selections * @param locator The locator of the selection input box * @param label The label for the ComboBox (optional) */ public static void selectByText(Selenium selenium, String text, String locator, String label) { if( label != null) { String disabledLocator = "//fieldset//label[.='" + label +":']/following-sibling::div//div[contains(@class,'x-item-disabled')]"; int timeout = 0; while( selenium.isElementPresent(disabledLocator )) { pause(waitDuration); timeout++; if( timeout > waitCycles) { throw new SeleniumException("Selection element was not enabled after timeout"); } } } boolean found = false; String downDownLocator = "//div[contains(@class,'x-combo-list')]"; String itemLocator = downDownLocator + "//div[contains(@class,'x-combo-list-item') and .='" + text + "']"; selenium.click(locator); for(int i = 0; i < waitCycles; i++ ) { if( selenium.isElementPresent(itemLocator) && selenium.isVisible(itemLocator)) { selenium.mouseDown(itemLocator); found = true; break; } else if ( selenium.isElementPresent(downDownLocator) ) { System.out.println("selectByText() - at least div for the combo is present..."); } else { System.out.println("selectByText() - no div for the combo present."); } pause(waitDuration); } if( !found ) { throw new SeleniumException("locator:" + itemLocator + " not found."); } pause(waitDuration); selenium.fireEvent(locator, "blur"); }
Hopefully this can help alleviate some of the pain out there around the GXT combo boxes and selenium.
Version Info
GXT: 2.1.1
Selenium: 1.0.1
Subscribe to:
Posts (Atom)
