Five Stars – What Customer Reviews Tell You About Your Business

I love to read negative reviews. My wife will tell you it’s because I’m a pessimist. I say because it’s where people tell the truth. Maybe I am a pessimist.

Here’s what I think each rating indicates:

*  Anger
** Frustration
***  Apathy
**** Dissatisfaction
***** Attachment


No question, one star reviews are the most damaging. Someone is upset, and they’re here to vent, and will probably bring in their personal problems. I’ve been there. And there’s not much you can do beyond damage control. Either you didn’t deliver at all what was promised, or this is just an angry person.


This is where I always jump to when reading customer reviews (on Amazon for instance.) These people wanted something and are frustrated you didn’t live up to their expectations. Here’s where you can learn what you did wrong and how you can do it better.


Almost never find anything useful. Either it’s someone frustrated being generous or someone content but pessimistic.


This is where I go next after two star reviews. Here, you have people who are generally satisfied, but there is something they didn’t quite like. Often it’s a personal preference, but maybe you’re 90% there. This is where good ideas come from.


Skip this entirely. These reviews are either true believers, or shills. Mind you, I’m not saying you don’t want 5 star reviews, just that they’re not going to tell you anything useful.


Sales and Marketing Software Frustrations

I have some experience with with sales & marketing software, and have done technical consulting for clients around email campaigns and Adwords. I’ve worked on e-commerce and CRM systems too. But that’s not my main focus. I’m a software developer and my specialty is testing & automation.

In the work I’ve done, I’ve been impressed by slick user interfaces and big promises (often illustrated by colorful charts), but I’ve always come away from those engagments frustrated, not just with technical complexity, but with an appreciation for the people who need to use these systems to do their work — which is primarily with people.

For instance, a salesperson who has to change the way he works into Salesforce for forecasting, a writer & SEO expert trying smoothly coordinate her marketing message across blog, social media, email and ad campaigns, or a fulfillment division trying to customize their order & support systems to handle their products that don’t fit a cookie-cutter mold.

I don’t think a single monolithic system that solves all these problems is the right way to go. For one thing, only a huge organization could afford something like this. Also, it’s bound to be as clunky and one-size-fits-all as any other existing system. And it would never get finished.

I think of how software is being made simpler with microservices and adaptive user interfaces. Let the users control their data and shape it the way they need it. Let the software provide the integration. Let domain experts define how they deal with it — the salesperson, the marketer, the writer, the SEO expert, the division manager, the CEO.

I think of how I write automation. First I understand the manual process, and then I try to understand the actual business requirements. Then I try to reconcile them and start with automating the parts that make the most sense, and provide the most value.

Sometimes it’s a combination of automated & manual steps that are more successful than either a fully automated or completely manual approach. And then, if you’re lucky, processes can change to make it even easier to automate once you have the confidence in your software — and the time freed from making it work for you — to think about what’s really important in your business.

I’d love to talk with people in these different roles and hear their frustrations and ideas for how sales & marketing software could be better — or even better, how doing their jobs could be easier — in spite of the software they currently have to use.

How to access elements when you get ElementNotInteractableException

My answer to this question on Quora:

How do I resolve the ElementNotInteractableException in Selenium WebDriver?

ElementNotInteractableException is caused when an element is found, but you can not interact with it. For instance, you may not be able to click or send keys.

There could be several reasons for this:

  1. The element is not visible / not displayed
  2. The element is off screen
  3. The element is behind another element
  4. Some other action needs performed (by the user) to enable it.

Strategies that may work to make it interactable (depending on the circumstance.)

  1. Wait until an element is visible / clickable
    WebDriverWait wait = new WebDriverWait(driver, timeout);
  2. Scroll until the element is within view
    Actions action = new Actions(driver);
  3. Use javascript to interact directly with the DOM
    JavascriptExecutor js = (JavascriptExecutor) driver;
                      element.value = 'whatever';")
  4. Perform whatever other action is necessary and possibly wait until after that.

Viewing or converting .flv video to .mp4

ffmpeg is a command line tool that can convert .flv videos to .mp4 (or another format).

ffmpeg -i video.flv -codec copy video.mp4

Ffmpeg is easy to script, but the number of command line options can be daunting.

Screen Shot 2018-01-09 at 4.42.52 PM.png

handbrake is a GUI application that can also convert .flv to .mp4.

Handbrake is actually a wrapper around ffmpeg that offers sensible defaults but still allows you access to many options.

Screen Shot 2018-01-09 at 4.38.41 PM.pngVLC is an app that can view .flv videos directly.  The VLC Player is free to use.

Screen Shot 2018-01-09 at 4.42.41 PM.png

Getting the spec name in Protractor for Sauce Labs

Say that you’re writing tests in Protractor, and say also that you’re running your tests on Sauce Labs.  You want to set your test name in Sauce Labs to match the spec.

You normally set the test name in Sauce Labs by sending “name” in the desired capabilities. = "your test name"

But in Protractor, the browser is created before starting the test.  The order of execution is:

1) Setup environment
2) Create a browser and setup globals 
3) Setup plugins 
4) Execute test cases 
5) Wait for postTest plugins to finish 
6) Teardown plugins 
7) Teardown

(in runner.ts)

The configuration file(s) are read and capabilities set in step 1.  Then the browser is created.  And only in step 4 are the spec files read.

There is an afterEach() hook that allows you to restart the browser for each test (if your test runner supports it, e.g. jasmine, mocha), and when using Sauce Labs (or Browserstack) to update the test status:

this.sauceServer_.updateJob(session.getId(), update, (err: Error) => {

(in sauce.ts)

We could use this updateJob method to also set the test name before each spec, but that would require changing the source code — it’s not available to the conf file or before each.

However, this same method can be called on the client side by using the Javascript executor.  So, in the beforeEach() method you can call:

browser.executeScript("sauce:job-name=whatever you want");

and it will change the test name in Sauce Labs. There is only one thing left to do to make this functional, get the spec name to set in the Javascript Executor.

This can be accomplished by getting the spec as a return value to the spec definition:

var spec = it('should set the spec name in Sauce Labs', function() { 
    browser.executeScript("sauce:job-name=" + spec.getFullName()); 

Now your tests in Sauce Labs reflect the text in your carefully worded spec description.

There’s one thing that can make this better.  Instead of adding this step to each spec, set it in your protractor conf.js file using the onPrepare() hook.

If you’re using mocha, no problem, but if you’re using Jasmine (the default Protractor test runner), well, this is a problem:

Let me just say here that often open source project maintainers pull the “because it is better” argument to mean “because I don’t know how”.  Ask Dostoyevsky about the mindset.

But, you could also use a custom reporter in Jasmine

onPrepare: function() {
        specStarted: function(result) { 
            browser.executeScript("sauce:job-name=" + result.fullName);
} }

If you add this to your protractor conf.js your tests will update with the spec fullname in Sauce Labs.

Here’s a working example:

Mapping Maps With Method References

I just learned about “method reference” notation in Java 8 thanks to Intellij IDEA code hints.

Consider the following code:

public class MapMap
   Map<String, String> map;
   public static void map(Object key, Object value)
      System.out.println(key + ":" + value);
   public void mapmap()
   { //...see implementations below }

I knew this:

/* loop */ 
for (Map.Entry entry: map.entrySet()) 
  map(entry.getKey(), entry.getValue()); 

could be replaced with this:

/* lambda expression */ 
map.forEach((key, value) -> map(key, value);

but I did not know about this:

/* method reference */ 

See the full gist here


See here for the official documentation on method references: