Category: Brixen

Preparing for the Coding Interview and Other Tales

Today, I am playing the long game. The one that involves intensive and thorough preparation to get a job where I will have complex and difficult challenges to enjoy. Challenges that involve writing code and not long, involved test cases that take a day to design and debug before I can move on to the next test case that is going to take a day to design, debug and write. I contacted a recruiter who specializes in L33t Coding Jobs and he said I would have to get comfortable writing code on a whiteboard. I am not totally certain of the value of these whiteboard coding exercises over just giving the candidate a computer and pair programming through a bite-size problem with them, but I am getting with the program anyway. If this is the hazing ritual I must endure to obtain the my dream job, then I will endure it.

My chosen guide for preparation is the one that everyone uses — Cracking the Coding Interview. I snagged a 5th edition copy and starting working through the first two chapters. There’s one thing I can say for solving programming puzzles with paper and pencil. It’s slow. Okay, I can say some other things too. It does force you to know by heart the core APIs of your language of choice. I got very familiar with the String and Character methods for handling the entire Unicode character set while solving the problems in the chapter about strings and arrays. Most of the problems are actually pretty decent at working my CS student brain back into shape. Some of the problems are just silly and require you to do something that is dumb and the solution they want you to implement is one that wouldn’t pass code review in a decent company. Like — Delete a node from a list given only access to that node. The answer is “Copy the data from the next node in the list and delete that node.” Of course, this doesn’t work if the node you are give access to is the last node in the list. Normally, I would look at this and think, “Either this linked list API is shit and needs to be re-written because this doesn’t fucking work or the person who wrote this clearly doesn’t have a clue how to use a linked list API.”

Given that there are 150 problems to solve in the book, my interview preparation is going to take a couple months. It is worth the effort to escape the manual testing monster that slowing devouring all my joy. Hopefully, they will replace me with a traditional QA type, so the other SDETs can focus on their automation when I leave. The downside to this is that I haven’t had any spare time to work on Brixen, which is making me have a major sad right now. My next step is to write an EnhancedPageFactory class and some annotation classes so that declaring one of the component wrappers in a page object basically works the same way as declaring a WebElement with a FindBy annotation. Of course, specifying all the data for the component wrapper is a lot more intensive that a simple locator for a WebElement, but I figured that could be handled with a configuration file which is declared by the annotation. The intent is to make all that messiness with having to build the component in your page object go away and become completely invisible.

The other thing that bogged me down with the Brixen work was discovering just how painful and difficult C# is when you are trying to assert equality between collections. By default, C# uses reference equality which is totally ridiculous in my opinion. Who the hell though it made sense to not compare the objects they contain for equality? This really pisses me off. There is an interesting library that does this for C#, but I ran into problems comparing values like 64 bit integers and 32 bit integers. This library doesn’t have some mechanism for upcasting the 32 bit value and then doing the comparison. It just returns false. I realized this when the the library I was using to deserialize data from JSON was taking values like integers and returning then as the type with the largest possible values. So, if I serialize an object with a 32-bit field and then deserialize it, I get a 64 bit value for that field. VERY ANNOYING.

QA Director has become a mite touchy on the subjects of under-staffing and our unstable test environments. Apparently, the California team is even more under-staffed than we are. This is supposed to make us less unhappy that we can’t accomplish our objectives without working nights and weekends, and the logical fallacy of this line of reasoning is totally lost on most people. Be happy about suffering unreasonable expectations because other people are being crushed harder by expectations that are even crazier? Of course, we just made an offer to a manager candidate to replace my boss who was fired two months ago as the sacrificial lamb on the alter of blame for our lack of success instead of hiring more people who would actually do some of the work. Unfortunately, this candidate seems to be of the same delusion that it’s better to have a team of people who are doing both the traditional QA work and the automation. This does not bode well.

If I didn’t already understand how little valued the SQA function is, I’ll share a small anecdote about our upcoming monster release. There was a feature that was supposed to be ready by code freeze. It totally wasn’t ready by then, but we said we’d give it the old college try and test it if they could get it done within a few days. A few days later, the engineering team responsible for writing it said it was all done and ready to test. The person testing this feature started the testing and found that none of the REST end points were reachable. The engineering team is in India, so there follows a back and forth dialog between her and the engineering team with 12 hour delays in between communications. It was working for them, so she must be doing something wrong. As the release date grew closer, the testing could not proceed because the feature just wasn’t accessible to the test team. A meeting was called to make the call about this feature, that went like this:

“So, can we release this feature?” the product managers asked earnestly.
“No, we haven’t tested it,” answered the QA team.
“Great! Let’s release this feature then,” replied the product managers.
“We said no. We weren’t able to test it,” interjected the QA team.
“We all know that when QA says no they mean yes, ” laughed the product managers. “So, we’re good to go.”
“No. We are not good to go. The feature hasn’t been tested at all,” replied the QA team. “Not even one little bit.”
“Why are you being so difficult? I thought you said it worked,” barked the product managers.
“We didn’t say that it worked. The developers said it was working on their machines,” said the QA team who are now texting their favorite recruiters on their phones under the table.
“The customers really want this feature,” whined the product managers.
“We understand that. They probably also want it to work too,” said the QA team.
“Fine. Let’s talk about this again in a few days. Maybe the customers can test it for us.”

This happens all the time.

Share This:

Optional Types and JSON Deserialization for C# for Brixen

Every small victory shall be rewarded with the next battle. Now that I have completed the task of doing the C# implementations of all the state beans in Brixen, I am planning the translations of the configuration beans. Preliminary research indicates that the closest equivalent to Java’s Optional type is the Nullable struct. And there is a tool for marshalling JSON data into object instances: Json.NET. Once I had established those facts, I had to tackle the same issue I had when approaching this problem in Java, which is: How do I distinguish between a missing key an an explicitly null value? And I determined that there is no built in way to do this and will require work on my part to make it happen. It also led to a funny Stack Overflow post where someone posted their implementation with the caveat:

I uploaded the implementation into a repository on Github, for everyone to use (no warranty, use at your own risk, etc… I’m in hospital with 6 broken ribs and under painkillers: if something doesn’t work it’s YOUR fault):

https://github.com/alberto-chiesa/SettableJsonProperties

So, I will most likely be following the guidance of someone who was under the influence of strong painkillers. I expect this will be an epic journey involving a lot more coding than was necessary to pull off the configuration beans in Java.

Share This:

In Which I Bitch and Moan a Bit More

First, I would like to bitch about C#. I finally translated the whole state Brixen Java bean package into C# and both the C# and Java versions are fully unit-tested. Yay! Second, C# needs something like Lombok _ASAP_. I did not fully understand The Giant Teh Suck So Much that it is to write all this freaking boilerplate for ToString(), Equals() and GetHashCode() over and over again until I enjoyed not doing it for Java classes for the last year. It’s glorious to open up a class file and Not. See. That. Shit. I am bummed there is no way to do the decorator pattern in C# as I have done it in Java. That little beauty of a design pattern _really_ cuts down on boilerplate. And Equals() for collections such as Dictionary, the equivalent of Map for Java, totally blows because it does reference equality, not ‘contains the same shit’ equality like Java Map implementations do. Seriously… what the fuck? Who thought that was a good idea? This took far far longer than I thought it would. I thought I would be done with the C# translation before Christmas and that I would be blazing through the Python implementation by now. Writing unit tests is tedious and time-consuming, but having caught some bugs with them, I am happy I have committed to doing them in tandem with the C# translation. But enough about that. Brixen marches onward and the source is available here. Looks like someone forked my repo a while back. I am flattered.

Today, I am _not_ gruntled. Far from it. You probably would have guessed that from the mere fact that there is a new post today. I had my annual performance review and the result was good, but not spectacular. I feel satisfied with this outcome and it is what I expected. This was a rocky year for me, and I did a few things which embarrassed the QA director. I publicly contradicted his goals and strategy on a fairly high-level initiative he was pushing, and I chewed out the Principal SDET over email for checking crappy page objects into the core of the automation framework without so much as a word with me over it. So, the chickens are coming home to roost for me. I have always had a mouth that got me into trouble before my rational brain could stop me. I have a habit of just expressing things in a way that others find too blunt and not diplomatic enough. I also have a temper.

Today was one of the days in which my rational brain was too slow out of the gate to catch up with my mouth. A junior developer is taking on the task of translating the regression suite I wrote to run against the new, totally rebuilt front end. I expected this task to be difficult for her. The regressions suite tests the application that has the biggest, most complicated UI in the entire customer portal. That shit is hard and complicated and the page object modeling is a non-trivial challenge. Today, she called a code review that included me, the Principal SDET and two other team members. In the midst of the code review, the question came up about labels I have attached to the test cases in JIRA which are reproduced on the test method as group names. I have a longer term plan for using those labels and the group name mappings as a way to dynamically select methods for specific functionality on the fly so that a developer can trigger a build that selects tests that cover the functionality they touched in their commit. Principal SDET claimed I had agreed to take the labels off the Jira test cases and the test methods. Problem is, I have near perfect memory for conversations going back months, and I knew that I had not agreed to do that. In fact, she and the QA director had backed down from it when it last came up. I disagreed with this assertion and before I knew it we were shouting at each other over the phone and she was refusing to explain why the presence of these labels was harmful to anyone.

After a chat with the QA director, I will be doing a presentation next week to explain why I did this and where it is going and then put it forth to the team to decide to chuck this or not. If they decide to chuck it, then I will copy all my work elsewhere and continue implementing a parallel test suite that uses this plumbing and present it to the development team when it is ready because this whole thing was meant to help them anyway. I have no idea where this came from and it is not the first time an issue which had been settled has been raised again from the dead where I am told I have to change how I did something without getting a clear explanation for why I need to. I am getting… weary of this. Principal SDET has a habit of honing in on trivial, non-architectural things which harm no one and making a giant fucking deal out of them. Test data storage formats are a giant bugaboo and apparently everything must and should be stored in a Java Properties file even though Java Properties files are flat, key/value pairs and there is no tooling I know of or that she can point me to which will allow me to suck in a Java Properties file containing serialized data that represents collections of objects and their state and instantiate collections of POJOs with it. At one point, the directory structure of the framework was a giant burning issue. If someone checked something into the wrong directory or tried to use Maven modules to manage multiple, related projects, they were not following ‘architectural’ guidelines. I have no idea what important architectural implications any of this has since they have NO EFFECT on how any particular subsystem interfaces with any other subsystem.

The code review barely touched on anything related to actual form and function of code. I don’t know if it is worth it in the long haul to stick around in this role. I like the challenge of the stuff I work on, but this perennial micromanagement and drama is getting really old.

Share This:

Why Can’t Vacation Last Forever?

I am feeling the post-vacation blues. Not only did I not win the Powerball lottery for the biggest jackpot in American history, I had the unfortunate luck of returning to work in the same week a major release was scheduled to go out. The release was originally scheduled the week before, but it was postponed, leaving me with the unenviable responsibility of being on the conference call for the go-live moment, scheduled conveniently at 11:30 at night. I had volunteered to do the release call while on the vacation, but was told that no one should work on vacation. Frankly, I’d rather do this on vacation because I don’t have to work the next day. I am a cranky jerk when I am sleep-deprived.

The vacation was exciting. We took a long road trip to take the kids to see both sets of grandparents and my sister in Philadelphia. My son keeps asking when we’re going back. I’m sure that being showered with far more presents than any kid actually needs has a lot to do with that. It’s probably also really nice to have a good stretch of time when Mommy isn’t glued to her computer. Guilt? Yeah, I have a lot of that and some to spare. While in TN visiting my parents, we took our kids to a lovely local playground where I managed to get the worst ankle sprain of my life. There is NO logical reason for spraining my ankle where I did. I didn’t step into a hole. The ground was flat and stable. All I did was step off a small platform, a step down of about 8 inches. My ankle just buckled underneath me.

I am proud that I had the fortitude not to scream out the various conjugations of the f-bomb since there was a crowd of small children running around and having a great time. I sat down, blinded by pain, and waited for about two minutes, breathing deeply, until I could calmly call Dan over and tell him I had managed to injure myself for no reason whatsoever. I limped to the car and somehow into my parents house. I was not able to walk on my ankle for the rest of the day. I had to use a pair of my Dad’s old crutches to get around. My sister, the physical therapist, said the healing process is about two to three months for a sprain this bad. I can walk on it now, two weeks later, but it still hurts and feels weak and unstable when it is not wrapped in an Ace bandage and ankle brace. To say the least, my first week back to work was strictly work from home.

Two days after we got home, we went shopping for groceries. On this fateful trip, our son fell out of a shopping cart and busted one of his front baby teeth. It was too damaged to salvage, so it had to be pulled. Yep, we are those parents. The parents who let their kid ride in the back of a shopping cart against all recommendations and warnings posted on the carts themselves as well as the warnings given by the dentists and doctors who have to treat kids who are injured by falling out of these carts every day. Heathcliff will be The Kid Who Is Missing a Tooth for three or four years before his permanent tooth comes in. He will also be The Kid Who Is Never Allowed to Ride In The Back Of A Shopping Cart Ever Again.

In the midst all this holiday excitement and the handling of physical injuries, I did not have much time to work on Brixen. Shortly before we left on the Big Christmas Road Trip, I converted more of the code base over to C# and discovered to my disappointment that the decorator pattern in the Java code base is not possible in C#. Extension methods cannot satisfy the contract of an interface. And since C# does not have the equivalent of default interface methods, I am basically shit out of luck with the decorator pattern in C#. Therefore… this codebase will be a lot more verbose because classes needed to implement multiple interfaces will have to inherit from an implementation of one of them and then provide implementations for the methods of all of the rest of them. So, that kind of sucks.

One of the nice benefits of doing this translation is that it brought to my attention that I had made a bad design choice for the ControllableBean and its associated builder. Reflection is in powerful tool, but it should be used sparingly. Here is the original source code for ControllableBean:

So, this is a total abuse of reflection. The two-arg setters for adding new controls should not take a control name and a class type for the bean. They should take a name for the control and an instance of the bean. This is a much more logical and simpler design and I feel like a dolt for not realizing this from the beginning. Here is the new and improved version of ControllableBean:

This is much better. This interface is easier to implement and easier to understand. These code changes will be uploaded to GitHub soon. Meanwhile, we’ll just keep this little over-complication a secret between ourselves, won’t we?

In other news, it seems that my company is finally going to allow us to use Sauce Labs. I honestly did not think that anything would come of the research into the cost of their services that I was asked to do a couple months ago. However, it seems that we are doing a trial run with them soon and there is a manager assigned to the task of driving it now. I am so excited I can barely contain myself. Having access to some decent infrastructure to run large Selenium suites would be a sea change for my team. It seems that my employer just might have finally taken a first step down the road to building Good Automation.

Share This:

Fumbling Around Like a Total N00b: Translating Brixen from Java to C#

I spent a week scratching my head over failed unit tests that were ultimately the result of jackass n00b mistakes, and sadly, they were not C# n00b mistakes, but Coding 101 n00b mistakes like not checking for null and failing to actually set the value of a property after validating the parameter for its setter method. Oh, and leaving off the parentheses for a method call. Thankfully, I didn’t turn to Stack Overflow for help. My reputation would have taken a severe nosedive for requesting help with such embarrassingly basic bugs. And this, my friends, is why you should write unit tests. It saves you from checking dumbass Coding 101 mistakes like this into source control where they can be found by your co-workers who might be tempted to slowly freeze you out from the important and rewarding work because they just can’t trust you to write a decent for-loop without a user’s manual at your side.

I still haven’t figured out how to write an integrated build script for Brixen that would compile, test and deploy both brixen-java and brixen-dotnet. I did however, take the time to learn some basic Nunit framework usage so that I could actually write some unit tests. I also tried to integrate Nlog logging into the unit tests, but for some reason, the logging statements don’t get output to the console in Xamarin Studio, so I took it out. I think I need to try this on a Windows system with Visual Studio.

When I started coding, I realized I had no idea how a standard .NET project should be organized. I went in search of a guide and found that finding such a thing was not all that easy. It’s as if there is this pervasive assumption in the .NET coding community that you should just know how to structure a .NET project by osmosis. With Maven, there is a well-documented project structure and there’s generally no question where something should live. Java enforces a directory structure convention for packages which does not exist in the C# world. YouTube came to my rescue in the form of a short, awesome video tutorial where the creator of the video explained that these things are in fact often hard to figure out because they are not explicitly documented by Microsoft.

After basically learning the basics of a totally different tool chain, I finally got something that I could check into the Brixen GitHub repo that I was not ashamed to call my own. So far, I’ve only translated a handful of the state beans into C#, but things should move faster now that I have surmounted some of the learning curve. The code is definitely going to be more verbose than the Java version due to the lack of a tool like Lombok. I have to write implementations of ToString(), GetHashChode() and Equals(Some Object) which is tedious. In Java, I can just throw a couple annotations on a class and these methods are auto-generated at compile time by Lombok. I’ve updated the corresponding Java classes too. In the source code I presented at the Selenium conference, I did not do any parameter validation for the setter methods because I wanted to cut down on the sheer volume of code I had to present. I am now adding back in the parameter validation that I cut out because it’s just a good idea to validate parameters. So, the Java code is more verbose than the code from my presentation.

The Decorator translation is a little harder to pull off in C# because I have to use extension methods to produce something like the default method implementations that Java 8 allows, but at least, thankfully, it is possible to do. I treated myself to the pleasure of reading explanations of why Java 8 was just totally wrong for allowing this atrocity into the language because it violates the very definition of an interface. This may be true, but default interface methods are just astoundingly convenient in ways that justifies the atrocity in my opinion.

Share This:

Learning a Foreign Language: Translating Brixen From Java to C#

I started translating the existing codebase for Brixen from Java into C#. I mistakenly thought this would be a quick and easy task because the syntax of C# appeared to be so similar to Java. Syntax Schmintax. I didn’t realize how fundamentally Java had arranged my thinking around How Development Works. My first jolt was discovering how bonkers I was for thinking that it would be a breeze to do this. I was thinking that all I would need to do is install a plugin for IntelliJ and I would be golden. If I couldn’t do that, surely I could just use Eclipse. Fast forward two weeks, skip over a lot of cursing and forehead slapping, and I am using Xamarin Studio. It took a while, but I came around to accepting that you just don’t mix C# and Java in the same IDE. It’s. Just. Not. Done. I also eventually accepted that C# isn’t platform independent, and developing in C# on a Mac is kind of whack.

My second more unpleasant jolt was that Maven doesn’t support C#. This one was a lot harder to accept. I thought it would just be a matter of adding some new dependencies in the POM for Brixen, adding a build plugin or two and I’d be good to go. I would have brixen-java and brixen-dotnet playing all nicely together and all I needed to do is type ‘mvn install’ and shit would just work. It was really hard, but I finally accepted that this isn’t how it’s going to be. I still have no idea how to do the build and deploy thing for the C# packages, but I decided to defer that task while I try to learn the C# language.

There’s no Lombok for C#, but there are these things called properties which sort of do the same thing. The naming conventions in C# are whack. Seriously?! PASCAL IS SO OVER! Interfaces can’t have fields?! The languages are similar enough on the surface that it’s not too difficult to translate from one to the other, but they are different enough that I am regularly irritated and pissed off in some fashion. It’s like a rash that isn’t bad enough to make you go see a doctor, but still annoying enough that you really really want a steroid shot JUST TO MAKE IT STOP ITCHING. I just have to say to all you people who love C# — WHY? Why do you love it?

Share This:

Brixen Decorators: What’s Changed

The basic concept of the decorators hasn’t changed. There are just more of them. I have added decorators for state beans, configuration beans and builders in addition to the decorators for the component implementations. The decorators help reduce boilerplate code by using a new feature introduced in Java 8: default interface methods. A class can implement numerous interfaces, but extend only one class. Prior to Java 8, this meant implementing the same methods over and over again in different classes extending a particular interface. After Java 8 however, a decorator interface can extend another interface and provide default method implementations for the interface it extends.

Here is an example of the PolleableBeanDecorator, which provides default method implementations for the methods required by PolleableBean:

The decorator defers all the PolleableBean method calls to the default PolleableBean implementation — PolleableBeanImpl. This is achieved by requiring a ‘provider’ for an internal reference to a PolleableBeanImpl instance. So any class which implements PolleableBeanDecorator needs to define an accessor method for this provider. Let’s have a look at the provider for a state bean:

I didn’t want to have a method in a decorator interface that would return a reference to the internal state bean itself because that would break encapsulation. So, I came up with the idea of a ‘provider’ which would give protected access to this internal state bean reference so that only a sub-class or a class within the same package as the provider would be able to access the internal state bean reference. The packaging structure I chose allows only the provider and its sub-classes, the decorator and other classes in their package to access the provider’s internal state bean reference.

Here is an example of a state bean which extends PolleableBeanDecorator:

DynamicControllableBean is a state bean for specifying a page object that contains one or more web controls which needs to be polled for state change of some kind, usually after an interaction with one of its controls. A drop down menu, for example, would need to be polled after interacting with the control that expands or collapses it to determine if the menu has expanded or collapsed as expected. The default implementation of DynamicControllableBean can only extend a single class, so its parent is ControllableBeanImpl.

It would be a drag to have to provide implementations for the methods required by PolleableBean which are exactly the same as the implementations provided in PolleableBeanImpl. By implementing the PolleableBeanDecorator interface, DynamicControllableBeanImpl can satisfy all the requirements of PolleableBean by providing only an accessor to a LoadableBeanProvider that wraps an instance of PolleableBeanImpl. Lombok helps reduce the amount of source code even more because the provider field only has to be annotated with the Getter annotation.

The decorators for the configuration beans operate in the same way. Here is the PolleableConfigDecorator and the provider for a configuration bean:

And here is DynamicControllableConfigImpl, a configuration bean which implements PolleableConfigDecorator:

Decorators for the builders was a bit trickier to pull off, but I managed to find a way. Here is the PolleableBuilderDecorator:

And AbstractDynamicControllableBuilder, which implements it:

This decorator implementation works by declaring a provider which wraps the builder implementing the decorator. The same state bean must encapsulate all the state for the component, so declaring a builder with a separate state bean instance wouldn’t work.

The decorators for the components haven’t changed, so I won’t post any examples here since it would just duplicate what I presented at the conference. The source code for Brixen is here.

Share This:

Brixen Configuration Beans: What’s Changed

The changes in the configuration bean package are mirrored largely by the changes in the state beans and the builders. The other change is that I added JSON type information to all of the configuration bean interfaces. When I originally conceived of the configuration bean idea, I foolishly didn’t consider the possibility that some configuration beans may contain other configuration beans as fields. So, I only added the type information to the LoadableConfig bean. Without this type information, Jackson cannot properly deserialize polymorphic types.

The other change is that LoadableConfig allows the definition of custom properties, through JsonAnyGetter and JsonAnySetter methods. It is entirely conceivable that one might want to define a configuration option for a page object which doesn’t have general significance to a class of page objects, but which is important for a specific context:

The ControllableConfig is the most significant new addition. This configuration bean is for defining the dynamically configurable options for a page object which contains web controls. This configuration also encapsulates the configurable options for each one of its controls:

There is a marker interface for a dynamic Controllable that needs to be polled on intervals for a state change via a FluentWait:

Here is an example of what the configuration source for a ControllableConfig would look like:

In the same fashion as the state bean and builders, there is a marker interface that is parent to all the control configuration beans:

The marker interface for a click control configuration bean:

It extends ClickableConfig which is a configuration bean for a wider class of clickable page objects besides controls:

The configuration bean for a hover control:

The configuration bean for a hover and click control:

And that’s a wrap for the changes in the configuration beans. The source for Brixen is available here.

Share This:

Brixen Builders: What’s Changed

One of the awkward things about the original version of the API is how data from a page object’s JSON configuration source is retrieved and handled. I wanted to do something that was more elegant and less cumbersome than the multistep process of the original:

  1. Querying the service for a configuration
  2. Determining if a particular dynamically configurable option is defined in the configuration
  3. Determining if the value assigned to the option is null
  4. If the value is not null, then retrieving its value from the Optional that wraps in the configuration bean and setting that field for the page object through its builder

All of the the builder interfaces now overload all the methods that specify a page object’s dynamically configurable options. One version of the method takes a value for the field, and the other takes a configuration bean. The builder implementations take care of all the steps listed above save the first step. They also handle the case where the configuration bean is null. All the client class has to do is query the configuration service for the page object’s configuration by String ID and pass the result to the builder. If there is no configuration defined for the current environment under test, then the service will return null. If the configuration bean which is then passed to the builder is null, the builder will do nothing with the bean and leave the default value for that field in the page object’s state bean unchanged.

Let’s look at a couple of examples. The LoadableBuilder, a builder for a basic page object, and PolleableBuilder, a builder for a dynamic page object which needs to be polled on intervals for a state change via a FluentWait, are basically unchanged since the conference except for the new methods which take a configuration bean.

The default implementations of the new setter methods do all the work of checking and retrieving the data from the configuration bean which was previously the responsibility of the class building the object:

The other big change is related to the total refactoring of how web controls and the page objects that contain them are specified and built. Each of the three types of controls described in this post has a builder, but there is also a builder for a page object containing controls which has methods for specifying the controls.

The marker interface for a control builder:

The marker interface for a click control builder:

It extends ClickableBuilder which is a builder for a wider class of clickable page objects besides controls:

The builder for a hover control:

And finally, the builder for a hover and click control:

There is a _lot_ of duplicated code for the hover control and hover and click control, just as is the case for their state beans, which I acknowledged in my post about the changes in the state bean package. For now, I don’t see a good reason for extracting the common behavior into a parent interface for both of them to extend because the parent interface wouldn’t be reusable in other contexts. It’s a wart on the butt of this API, but I think I can live with it.

The interface for the builder of a page object which contains one or more web controls has a lot of syntactic sugar that allows you to build the whole page object, complete with all its controls if you don’t want to use the individual builders for the controls themselves. Each control is associated with a String ID that must be unique (which should go without saying, but I couldn’t help myself):

Share This:

Brixen State Beans: What’s Changed

At the conference, I presented source code for Accessible and Dismissable objects, that is page objects which can be rendered visible or invisible by user interaction. Because some objects are dismissable, but not accessible, such as announcement dialogs and popup ads, I modeled them as separate entities with their own state beans and used a marker interface, ToggleableVisibilityBean to specify the state for a component which is both. There are some limitations with this design approach. First is the built-in assumption that there is only one control which toggles the visibility of the component, which is not true in some cases. A chooser dialog can actually have three such controls: Submit, Cancel and Close. The other is that the controls themselves are also page objects, but they are not modeled as standalone entities.

So, I decided to re-work the concept entirely. I created a state bean interface for a component which contains controls. It allows any number of controls to be added to the component’s state specification. It also makes no assumptions about the side effects of interacting with the controls. Therefore, it is generic and applicable to any such component, whether it is a component with toggleable visibility, or which has filterable content or with pagination behavior. Big win for reusability!

Here is the source for ControllableBean, the new state bean for a component which contains web controls. This is a terrible name, and I am open to suggestions for something better. At least it’s shorter than ToggleableVisiblity:

Each control is associated with a name, and the ControllableBean interface has syntactic sugar setter methods for defining the state of each of its controls. There are three distinct flavors of controls:

  • Controls that are visible by default and have meaningful behavior when they are clicked
  • Controls that are are visible by default and have meaningful behavior when they are hovered, such as expanding a menu
  • Controls that are are invisible by default, must be hovered to make them visible and that have meaningful behavior when clicked and which also can have meaningful behavior when hovered

The first type is a vanilla, garden variety web control. The third type introduces some complicated test cases that I have to try out. There is a pretty complex text case I described at the beginning of this post that I have to test with this new version of the API. That same post also explains an additional shortcoming of my original design, having to do with the fact that in some environments you just can’t trigger the mouseover action through Selenium or through Javascript using the JavascriptExecutor. I spent some time thinking about possible dynamically configurable workarounds for interacting with the control in such a way that the side effects of the interaction can be triggered, allowing a tester to automate tests which rely on that workflow to test something else. Obviously, you’d have to manually test the hover action because you can’t automate it, but it would be great if that didn’t block the automation of other tests.

For the second type of control, you can often just click it to trigger the same side effects that the hover action does. So, I added two dynamically configurable options to click instead of hover. One for using native Selenium and one for using a Javascript click workaround through JavascriptExecutor in cases where the native Selenium click fails silently. For the third type of control, when you can’t hover the control either through native Selenium or the Javascript hover workaround, you just can’t make the element visible. So how do you click it? By using the Javascript click workaround through JavascriptExecutor, which will execute the click even if the element is not visible.

Yes, I know this is whack. I know that when you must resort to this hack for a clickable control, regardless of whether it is the first type or the third type in my list, you probably should add a test for the click action to your manual test suite. But, the intent of the workarounds is to enable automation of the workflow for other tests without ugly-ass boilerplate if-then-else clauses, or worse, hard-coding the workaround by default for all environments into your page object which makes tests for the click action suspect for all environments.

The hoverable controls have what I call an ‘unhover’ element (another awful name, I admit). This is a WebElement to use for removing focus from a hoverable control. It should be an element in a safe location which itself has no meaningful behavior when it is hovered. This element also has the same set of workarounds as the control — hover with Javascript when the native Selenium hover action fails silently and the focus is not removed from your control as well as the two click workarounds when you just can’t do a mouseover by any means. Just be sure that the control also has no meaningful behavior when it is clicked!

I have another state bean marker interface for components containing controls which have dynamic state changes when one interacts with their controls. This dynamic state change should polleable on intervals with a FluentWait to determine if the expected state change has been achieved:

Let’s take a look at the new state beans for the controls themselves. ControlBean is a marker interface that mostly serves for type determination and it’s the parent to all controls. You gotta love Java 8 for default interface methods:

ClickControlBean is a marker interface for the first type of control in the list.

It extends ClickableBean, which is for defining a wider class of clickable elements besides controls:

HoverControlBean specifies the second type of control on my list:

HoverAndClickControlBean specifies the third type of control on my list and it is a PolleableBean due to the fact that this type of control has dynamic visibility, which means it should be possible to poll it on intervals with a FluentWait to determine if it has been toggled visible or invisible after hovering it.

I am not happy with the amount of repeated code in the two hover control state bean interfaces. I don’t think it’s worth re-working the inheritance hierarchy here since a parent class that defines the shared methods probably isn’t reusable anywhere else.

So, there you have it. The source for Brixen is available here, and it has complete Javadoc comments for all but a small handful of classes.

Share This: