Monthly Archives: February 2013

Three steps to Social HR

The leftover dogma from the industrial revolution has to be removed from company culture in order to avoid an arduous path. The workforce is moving away from the repetitive motions of factory work. Norms developed to push people to their limit must be shed.

The modern workplace is all about sharing knowledge, social employee recognition, staff engagement, and interconnectedness. Embrace the ever-increasing hyper-connected social society in your workplace, and reap the rewards of an engaged innovative environment.

1. Use social enterprise software to interconnect and brainstorm with your staff

Communicate with your staff through Yammer, an internal enterprise social network. Yammer is a lot like Facebook’s wall, allowing communication with your entire staff. If one person has a problem in your company, they can ask on Yammer allowing anyone to answer.

Then, introduce social employee recognition. Many companies already have an employee recognition system in place, but most homegrown solutions are isolated. Our application, Recognize, provides a needed social element to employee recognition. When employees are recognized publicly, they’ll be more profitable. Regularly recognized employees are more dedicated to the organization as well as feel better about themselves.

Move away from your isolated intranet. Aragon Research predicts by the end of 2014, social intranets will replace conventional, information-driven intranets. Ones that connect with third party applications and allow real-time collaboration, allow for new ways companies can get the most from their staff.

Much like Yammer and Salesforce, choose tools that allow seamless integration with your technology workflow. In Recognize, we are working to completely integrate with Yammer, Google, and eventually Salesforce. Being integrated is key to surviving the modern enterprise technology landscape. One way to find apps that are connected is by looking in Yammer’s App Directory. The Business Tools section on Google Web Store is another way to find web apps.

2. Give more responsibility to your staff

Let your employees choose their job title. I love this idea ever since I heard it being practiced at Amazon. I even mentioned it in a previous post. It gives more ownership to the employees and suggests the employer trusts them. It may be a small gesture, but many small gestures add up. When employees feel they have more ownership, they’re more engaged.

Eliminate the 30 minute daily break. We are using our minds more than our bodies, and we need proper mental breaks. Strict rules like two 15-minute breaks implicitly assume the employer doesn’t fully trust their employees. Let your employees decide when they are ready for a break. Thus, your staff will more alert and able to handle challenging tasks.

Create an environment where everyone’s opinion counts. That’s why Yammer and social collaboration tools work so well. People can articulate and share their ideas on an equal playing field. We need to start applying this idea more in the real world. Build a “living wall” where employees physically write on a wall in your office. This act is empowering for employees. It is visible to everyone in the office, and allows everyone an equal opinion.

Bring Your Own Device (BYOD) is a recent trend in business. Not only do businesses save money when they allow their employees to bring their own monitor or device, it gives your staff more ownership over their lives at work.

3. Encourage more physical activity

When people do tasks together, they feel more connected. Introduce activities where the staff can collaborate in games, outdoor activity, or exercise.

Open an exercise room in your office. A room with a couple of ellipticals and a ping pong table will go a long way. Host daily exercise or yoga classes at the office. When people have exercised they are more relaxed and think more clearly.

Throw monthly parties celebrating employee achievements. Using employee recognition tools like Recognize can help with this. No matter what employee recognition platform your company uses, celebrating your staff with beverages and awards each month helps company culture and office positivity.

Throw bimonthly parties with TED-like talks from staff, and celebrate company projects.

Open up and embrace social

Using enterprise social web applications, providing more ownership to your employees, and fostering an environment of activity will lead to a better workplace for you and your staff. You’ll see more innovation and collaboration.

How is your company providing a social environment in your office? What are your concerns with an open culture?

Testing tips with Capybara on Rails

Downtime, layoffs, security breaches, and bugs are among the worst things that technology teams have to deal with. Surprisingly, bugs are the most manageable. To help make bugs more trivial, here are a few application testing techinques when working with Rails.

Any time you deploy new code, you need to have confidence the new code works as advertised and that old code hasn’t broken down. There’s no way to have 100% confidence, but having good code coverage is a start.

Rails provides many ways to test, but in my opinion the two most important ways are unit tests and integration tests. Unit tests examine your low-level model code, and makes sure core functionality doesn’t break. In any modern web app worth its salt, you will need full-stack integration tests. How do you know that an Ajax action actually replaced the element you thought it would?  Functional controller testing is decoupled, but assumes form parameters are sent through in a certain way, but what if there is a bug in your html? You need to be able to reproduce user behavior exactly as a user behaves, with no assumptions. This couples things, but that’s ok. Better to be coupled and catch a bug, than not catch it all.

We use capybara and capybara-webkit for headless browser testing. I have a love/hate relationship with capybara. On one hand it provides the best full stack testing interface for a Rails app I’ve ever seen and has saved me countless hours of debugging.  On the other hand, I”ve hit so many weird synchronization issues (due to the asynchronous nature of ajax) with capybara and capybara-webkit and spent countless hours pulling my hair out.  See this discussion on Capybara’s google group (https://groups.google.com/d/topic/ruby-capybara/sjgRGiNcL7g/discussion) and this one on capybara-webkit’s (https://groups.google.com/d/topic/capybara-webkit/i51R5I4sMCI/discussion)

They are not without faults, but the gains are so worth it when you see your test suite go green prior to a deployment.  Also, most of Capybara’s synchronization’s issues have been solved in their latest version, I think > 2.0.  Shout out to Jonas Niklas for his great work on this project.

I do have a small bone to pick though. Prior to v2 of Capybara, it had this nifty helper method called #wait_until which I used heavily to wait until an element appears.  In v2 this was removed, see: http://www.elabs.se/blog/53-why-wait_until-was-removed-from-capybara.  Jonas says that there shouldn’t be any synchronization issues any more and that if there are its really just a matter of how you are testing.  Hmm… test suites should get out of your way, no? Not tell you how to write your tests?  I don’t know, perhaps he’s right, but I didn’t look kindly on rewriting our massive test suite.  Luckily, Jonas is so awesome he provided this workaround that plugged and played right into our suite: https://gist.github.com/jnicklas/d8da686061f0a59ffdf7

def wait_until
  require “timeout”
  Timeout.timeout(Capybara.default_wait_time) do
    sleep(0.1) until value = yield
    value
  end
end
Awesome.  Also, here’s a nifty capybara pattern I just came up with and posted on my personal blog, http://p373.net/2013/02/22/capybara-custom-matcher-alternative/
If you want to add functionality to a Capybara::Session, or “page”, where you need to check multiple things, and want to do it in a DRY and reusable fashion, check this snippet:

#Let's say you want to check super awesomeness on the page
#which involves checking multiple things, like the current path,
#the page has some content, and a particular css selector is present
#Like so:
page.should be_super_awesome

#in spec_helper.rb
Capybara::Session.send(:include, SuperAwesomeHelper::Session)

#The the implementation:
module SuperAwesomeHelper
  module Session
    def super_awesome?
      errors = false
      errors ||= "Wrong path" unless current_path == super_awesome_path
      errors ||= "Missing content: You are awesome" unless !errors and has_content?("You are awesome")
      errors ||= "Missing selector: #awesome-div" unless !errors and has_selector?("#awesome-div")
      People.all.each{|p| errors ||= "missing person #{p.name}" unless !errors and has_selector?(".person-#{p.name}")}
      !errors or raise Capybara::ExpectationNotMet, errors
      return true
    end
  end
end

Check the p373 blog post for all the gritty details.

Recognize launched in Chrome Web Store

Our goal is to make Recognize as easy as possible to use. Eventually, we will have a Chrome Extension, Dolphin Browser plugin, iPhone app, Android app, and a Windows 8 tile app. We will partner and integrate with Salesforce, Intuit, Yammer, and others to make Recognize a part of your workflow.

Today, we stepped towards our goals by launching in the Chrome Web Store.

Add Recognize to Chrome now

Launching in the Chrome Web Store is a great way for us to show the cool features Recognize has to offer. Plus, it allows people to launch Recognize from their Chrome web browser. This makes it easier to use Recognize.

We have a long ways to go with all the things we want to do. Each step we make we get closer to a seamless experience for coworkers to record greatness.

Minimalist business card design

Business cards are too busy.

Many business cards portray the opposite of minimalism. They have unnecessary graphic art elements, and place content in the corners of the card. They often include their name, their email, their website, their phone number, their office number, their fax number, and their address. Phew! Business cards would be easier to read and easier to focus if they only included what was absolutely necessary.

Do you we really need your job title on a business card?

When designing with minimal on the mind, a lot of information is omitted. First to go is address. Addresses are not needed for most businesses. Hardly anyone is going to visit me, so I omit it. But if you are a brick and mortal store then it makes sense. Next to go is the job title. The fact that Amazon let’s their employees choose their job titles says a lot. If it is important to know the job title of someone, then ask them.

The point of business cards is for someone to remember you.

What kind of conversation is it if the person who receives the business card doesn’t know anything about you? All you need is their name. Their name plus the company name will give enough information to remember that person. Find out about them during the conversation, and then use the business card only as a frame of reference.

Minimalist design is the goal.

The best products are ones that allow the users to focus. Things that are not important, or key to the product, get in the way. This philosophy extends throughout my life. When I designed our business cards, this was my primary goal.

Recognize’s business card

Recognize's business card

People love our new cards. They love them because they are focused and unusually simple. People hand me busy cards with all kinds of graphics and information. Recognize’s card has just has 4 pieces of info: name, company name, email, and telephone.

What’s more, people feel comfortable with centered information. That’s why I put our logo on one side centered, and our basic information on the other side also centered. People immediately know the company name and my name.

I only included our email. A good friend pointed out on my old personal business card, “Hey your email has your full name and your URL. Redesign it with just your email and that’s it.” In the end, I redesigned my personal card to only have email, phone number, and city. The other side is completely blank. People love this design. This influenced my design process on Recognize’s business cards.

My personal business card

Print on recyclable material

A few obvious design requirements to a simple card include only using a few colors and use only one typeface. Beyond that, I recommend using Moo.com to print your business cards, and use their recyclable paper. We don’t need more business cards in landfills.

We opened our Startup Package to the public

Stream page on Recognize

I am very proud to announce our Startup Package, all the primary features a company needs to start recognizing their staff. Anyone can sign up today from our Homepage.

Our signup process delivers a seamless experience on both mobile and desktop.

We put a lot of time and effort into making it as easy as possible for users to sign up. We ask a total of six questions over two sections. First, we ask for a company email, company name, and password. If they are the first user of a company, then we immediately log them into our on-boarding process.

On-boarding is only three sections, we ask for their name, if they want to add a team, and finally if they would like to invite any teammates. It is a great experience on all devices.

Less is more

Send recognition page on Recognize

Other enterprise recognition applications complicate the process by including too many features. Recognize simplifies this by only having users send messages to each other. We don’t tie money to our system, and we don’t hinder users by requiring them to setup goals.

Recognition detail page
If your company wants to reward your staff with money, then host recognition parties every month. Hand out gift cards to the employees who send and receive the most recognitions. Give money rewards to employees who get to certain point levels in Recognize. We want you to control your money, and use Recognize to help guide employee reward decisions.

But we recommend using the inherit nature of competition to fuel success in your work. Cash rewards lead to employees externalizing their motivation, possibly lowering satisfaction.

Reporting page on Recognize

Responsive design: Recognize supports Mobile, Tablet, Desktop, and TV

We worked very hard to make Recognize great on all devices. Unlike most web apps, ours doesn’t block you if you try to use Recognize from your phone. You don’t have to download anything! Simply go to recognizeapp.com on your iPhone, Blackberry, Android, or tablet, and you’ll see that it performs just as well as the desktop experience.

Recognize stream page on iPhone

We didn’t just provide responsive styles, we also optimized your mobile experience. We took advantage of touch technology,  making your experience on Recognize half a second faster than most mobile websites.

Team management is baked into the Startup Package

Team show page on Recognize
We heard loud and clear from talking to businesses that teams are very important. We made teams an integrated component.

Recognize is the ideal solution to spark Social HR in your workplace

The idea of Social HR is to use tools and solutions to connect your employees. Tools like Yammer and Recognize are both great ways to further engage your employees through technology.

Take Recognize for a test drive and sign up right now.

Runway: a new shared workspace in San Francisco

Runway hallway and meeting area.

After seven months of working from our homes, Peter and I have moved into Runway SF, a coworking space. Even though it recently opened, it already consists of a number of startups, technology companies, and related businesses. We were lucky and had a connection through a colleague who introduced us to Runway’s office manager. We grabbed two window seats.

Recognize's workspace at Runway SF

Runway is the cool new kid in the shared workspace community

This space is really cool. First of all, it is in the Twitter building, along with Yammer. Considering that Recognize is partnering with Yammer, the location couldn’t be better.

The long hallway, or runway, is filling in with companies. Every day new companies are moving in. We really got in right at the beginning. Runway doesn’t even have a website yet.

Runway space itself has a lot going for it. The space includes a nice bar, igloo-like meeting room, sound proof conference room, lots of windows (that open!) , kick-ass meeting event area, and you can easily play frisbee 🙂

The igloo meeting room

Igloo light up meeting room
What is really cool about the igloo is the light show it puts on via remote control.

Bar

The bar
The bar area is usually stocked with beer and liquor. Plus it touts a great ice machine, and sorted compost, recycling, and garbage.

Corner hang out / party prep area

Corner of Runway
Back in the far SW corner overlooks Market St. It has a small kitchen table, arcade console beer keg contraption, and a big refrigerator.

All this space needs is a ping pong table!

Using console.time to test strategies appending HTML while in loops: createElement, innerHTML, and jQuery append.

I have long heard that innerHTML is faster than creating elements, when you don’t need to store the DOM element in Javascript for further use. I had to do one such manipulation on Recognize’s pricing page.

Recognize’s pricing page copies text from the right features column for mobile considerations.

On page load our pricing page grabs the text of the features on the right column, and inserts the same text into the corresponding row. You can’t see it unless you resize your browser down to the size of a phone. We show the hidden copied text for mobile devices, because we can’t fit that right features column on 480px width devices, like the iPhone.

Recognize pricing page on an iPhone 4

Recognize pricing page on an iPhone 4

I want this to happen fast. Because I loop over the DOM, the data is stored in the existing HTML. This is expensive, but allows me to keep my data DRY, and allow for devices that don’t have JS to at least view the site. Not to mention that it is important for the features to be in the HTML for SEO.

I profile my functions with console.time and console.timeEnd. For instance:

  function funStuff() {
    console.time("funStuff finished");
    // Do something expensive
    console.timeEnd("funStuff finished");
  }

That will output a time in the console. You can learn more about console helpers at Firebug’s Console API docs.

Let’s get down to business with my code on the Pricing page. Here it is with my first attempt, using document.createElement to append the HTML:

  P.prototype.copyFeatureText = function() {
    var $features = $("#features li");

    $(".features").each(function(j, el) {
      var pricingFeature = this;
      $features.each(function(i, el) {
        var span = document.createElement("span"),
            listItem = pricingFeature.getElementsByTagName("li")[i],
            text = this.innerText;

        span.innerText = text;
        listItem.appendChild(span);
      });
    });
  };

I’m doing a lot here. I’m looping over each feature’s list (Startup Package and Business Package), and for each line I create a new span and give it the same text as the corresponding feature’s list. It looks slow.

I run this 10 times to have a decent sample size.

The results in milliseconds:
43.698
44.765
45.872
45.381
45.101
45.932
57.034
37.946
36.279
44.404

Using document.createElement, this operation took on average 44.641ms.

Okay, I rewrote copyFeatureText function to not store so many variables and to use innerHTML instead of createElement.

  P.prototype.copyFeatureText = function() {
    var $features = $("#features li");

    $(".features").each(function(j, el) {
      var pricingFeature = this;
      $features.each(function(i, el) {
        pricingFeature.getElementsByTagName("li")[i].innerHTML += ""+this.innerText+"";
      });
    });
  };

I run the profiling again. Here are the results in milliseconds:

56.768
51.154
56.942
45.673
49.746
38.897
45.057
48.204
53.077
51.538

With string concatenation and innerHTML, it takes slightly longer at 49.706ms.

The results show that for this specific operation, it takes around 5 milliseconds longer with innerHTML. Somewhat counter intuitive on first impression due to the decreased lines of code. But knowing more about what is happening under the hood with +=, we find that += can be a slow.

Clearly, appending elements on each list item slows down the operation. It seems for my uses it is necessary, unless I was to strip out the entire DOM list item nodes and replaced them with a documentFragment. A strategy I believe to be overkill.

To avoid += string concatenation, many suggest using Array.join(). Modern browsers, like Chrome, don’t show any difference in performance. But let’s test anyway using this strategy, plus using jQuery to append a string.

  P.prototype.copyFeatureText = function() {
    var $features = $("#features li");
    
    $(".features").each(function(j, el) {
      var pricingFeature = this;
      $features.each(function(i, el) {
        var listItem = pricingFeature.getElementsByTagName("li")[i],
            span = [];
            
        span[0] = "";
        span[1] = this.innerText;
        span[2] = "";
            
        $(listItem).append(span.join(""));
      });
    });
  };

Here’s the results:
47.092
49.399
41.382
43.525
63.440
53.579
62.801
58.524
56.857
60.428

Appending a string via jQuery takes on average 53.703ms.

That is slower. Makes sense considering it uses jQuery. jQuery does quite a lot and can slow things down a bit at times.

I can see one way I can quickly make this last example more performant, only reset the second index of the span array.

  P.prototype.copyFeatureText = function() {
    var $features = $("#features li");
    var span = ["", null, ""];
    
    $(".features").each(function(j, el) {
      var pricingFeature = this;
      $features.each(function(i, el) {
        var listItem = pricingFeature.getElementsByTagName("li")[i];

        span[1] = this.innerText;
            
        $(listItem).append(span.join(""));
      });
    });
  };

The results are better:
53.848
36.993
57.184
40.089
54.411
52.891
59.836
48.242
49.737
49.209

Only creating an array once, and only changing the text array index in the loop takes 50.244.

Okay so slightly faster.

Looking at the results, it looks like for now I’ll keep doing exactly what I was doing with document.createElement even if the difference is only a few milliseconds in Chrome.