Newer posts are loading.
You are at the newest post.
Click here to check if anything new just came in.

January 27 2014

14:00

How to Use New Relic Custom Dashboards & Why You’d Want To

Today we’re going to look at New Relic custom dashboards. Specifically, I will show you three ways that I tend to use custom dashboards:

  • creating an overview dashboard from existing charts
  • creating your own charts from existing data captured by New Relic
  • creating dashboards for your custom metrics

But, before we get into any of that, we must first ask ourselves a question, why should we use custom dashboards at all? New Relic does a pretty good job of presenting your application performance data. Just using the regular UI, you can glean way more information about the performance of your app than you ever could have before you started using New Relic. So, before I show you how to use custom dashboards, I’ll explain why I think anyone using New Relic should look at them sooner rather than later.


Why Use Custom Dashboards at All?

It’s true, most people happily use New Relic without ever looking at the custom dashboard functionality that it provides. It’s not until you’re a fairly advanced user that you may decide to look at custom dashboards and see what they have to offer you. I think this is a shame, playing around with custom dashboards can not only allow you to slice and dice your app performance data in different ways, but can also:

  • teach you quite a bit about how New Relic captures metrics
  • allow you to learn exactly what kind of data gets stored for the metrics that get captured
  • teach you about the limitations of New Relic charts

You can learn all those things by reading the documentation, but playing around with custom dashboards, allows us to begin to understand some of these things by example (on a more intuitive level), rather than just knowing it as a bunch of dot points. As is often the case with technology, tinkering with an unrelated area of a tool, will sometimes give you more insight and understanding into how the more commonly used areas of the same tool work. Using custom dashboards will make you a more savvy New Relic user, and if you’ve read the other New Relic posts that I’ve written, you’ll know how I feel about knowing your tools.


Creating an Overview Dashboard from Existing Charts

The one custom dashboard I always like to build is what I call ’24 hours at a glance’. I take a bunch of existing charts that I consider important for a single application, lock the time period to the last 24 hours and put them all together on one dashboard. Whenever I am looking at a specific application in New Relic, this will be the first screen I look at to see if there is anything particularly bad that jumps out at me from the last 24 hours. Let’s see how we can build this kind of dashboard.

Firstly, we need to create a new custom dashboard. In the New Relic UI click on Dashboards->Create custom dashboard. On the next screen, we give our dashboard a name (you could use “24 hours at a glance”, or your own name) and pick the grid layout. Essentially, grid layout is a collection of charts all the same size and overview layout is one big chart surrounded by a bunch of smaller charts (we will use overview layout in the next section).

01_create_dashboard

Now we need to select the app for which we want to create our dashboard and then find some relevant charts to add. I like to add the following:

  • server average response time
  • historical server average response time
  • browser average response time
  • error rate
  • throughput
  • historical throughput
  • application CPU usage by host
  • application memory usage by host
  • top five web transactions by wall clock time
  • downtime
  • top countries by throughput
  • top five database operations by wall clock time

Depending on your application you may want to add some others, but I find this gives me a fairly good snapshot of what’s happening with the application and what to investigate if anything is wrong. Let’s find one of these charts and add them to our new dashboard. The server average response time is an easy one, as it’s the big chart in the Overview section of the Monitoring tab for an application. Each chart in the New Relic UI has a little New Relic logo in the bottom right corner, when you hover your mouse over this logo it turns into a plus sign, clicking on the plus will allow you to add this chart to a dashboard:

02_add_chart_to_dashboard

But before we add our chart, we need to change the time window for the New Relic UI to be 24 hours. We need to do this in order to give ourselves the ability to ‘lock’ the chart to the last 24 hours when we actually add it to the dashboard (this is awkward UX in my opinion, but at least we have a way to do what we need):

03_change_time_window

We can now go ahead and add the chart:

04_add_chart_to_dashboard

Don’t forget to tick the Lock to span checkbox. When we now visit our new dashboard, the chart we’ve just added should be there:

05_dashboard_with_one_chart

We can rinse and repeat the above process until we’ve added all the charts that we want. In the end, it should look something like this:

06_full_dashboard

You can click the Edit dashboard button in the top right corner which will let you drag the charts around and arrange them in the order you want. The only thing to note is that you can’t modify the individual charts in any way (for example, you may have wanted to have a more descriptive chart title, but you can’t change it) since they are standard New Relic charts.

The other custom dashboard I always like to build from existing charts is the ‘All applications at a glance’. This is only applicable if you have multiple applications you’re looking after. Here we pick one or two of the most important charts for every relevant application and put them together. It’s usually a safe bet to use the ‘Response Time’ chart from each application. The actual process of putting the dashboards together is the same as described above, you’ll just need to switch applications to get the relevant charts from each. In the end, you should end up with something like this:

07_all_applications

This is the screen I’ll tend to look at first, when I log in to New Relic. It may be useful to lock the time of each chart to 24 hours just like we did for our ’24 hours at a glance’ dashboard, but that’s up to you. Of course, this is only relevant if you’re supporting multiple applications. Having said that, if you have multiple pre-production environments for your application (for staging or load test), you may want to put them all together into a dashboard similar to this one, it may help you catch changes that degrade performance before the code ends up in production.


Creating Your Own Charts from Existing Data

The New Relic UI suffers from some necessary limitations. It needs to be all things to all people, so they can only group together charts and tables that would make sense for all web applications. Most of the time the UI screens will limit you to looking at one transaction at a time and one or two sets of metrics at a time, if you need to access others you have to click around. The good news is, with custom dashboards, this limitation no longer applies. We know which transactions are related within our domain, we also know which metrics are important to us on a per transaction basis. We can build a dashboard that groups together several related transactions with all the important metrics for each and look at it on the one screen.

Let’s say we have a particularly important transaction in our application, it might make sense to have a dashboard where we can see most of the important information about this transaction at a glance. Here on Tuts+ we have a concept of articles (obviously) and articles are pretty important to us, let’s build a dashboard to keep an eye on them.

Once again we need to create a new dashboard just like before, we’ll call it ‘Article overview’, but this time we’ll use an overview layout. We don’t have to go hunting for charts as we’ll be creating our own custom charts, so click the big button to create the main chart for our dashboard:

08_add_custom_chart

It will ask you if you want to add a chart or a table, we will add a table later, for now choose chart. You will see a screen that looks like this:

09_new_chart

The main thing to look at here is the metric that you want to display. When you click inside the metrics text-box it will drop down a list of top level metrics that you can select. The metrics in New Relic are named as prefix/category/label. In the case of a Rails app, the prefix might be Controller or ActiveRecord (if you’re not using Rails, the prefix for transactions will be WebTransactions). For Controller, the category would be the name of the controller and the label will be the action name. If you explore some of the metrics while you’re playing around with your first chart, you will start to have a feel for the kind of metrics you have access to and where to find them. If you don’t see the metrics you expect, make sure that you have the right application selected within New Relic, this always trips me up.

Back to our main chart. The metric we’re after will be tied to our ArticlesController, so its name is Controller/articles/show. Once we’ve picked the metric, the contents of the Value drop-down will change to contain all the values that make sense for this metric. It’s worth once again exploring all the various values and seeing what the resulting chart actually contains. In our case, “Average response time” seems like a good thing to have as our main chart.

At this point, if we give our chart a title and click the preview button we can see what it looks like:

10_articles_preview

This looks OK, but I want the Y axis to be in milliseconds and I want the units on the axis as well. So, let’s drop down the advanced options for the chart and change the number format to be ‘To Milliseconds‘, we will also set the Y-axis unit label as ‘ms‘:

11_filled_out_main_chart_form

Our chart now looks good on the preview. The only thing of note that we haven’t talked about is the Chart click-through drop-down. This essentially allows your chart to be a link to another custom dashboard, when you click on the chart, that dashboard will be displayed. We don’t need this functionality, so we leave the drop-down alone. We’ll now go ahead and save our chart.

12_completed_chart_preview

We can now add the various sub-charts. In our case, I happen to know that Tuts+ has a concept of tutorials (also, obviously) which is closely related to articles, so if I am going to keep an eye on article average response time, it’s probably a good idea to have a tutorial average response time close by as a comparison, so I will create a chart for that. We’ll follow the same steps as above, in the end our dashboard will look like this:

13_article_and_tutorial_dashboard

Hmm, it looks like the average response time for articles is much higher than tutorials, but I happen to know that both of them share a significant amount of code, strange. But it’s also an indication that our custom dashboard is already paying dividends and we haven’t even finished constructing it yet. I could have found this information by looking it up in the regular New Relic UI, but having the charts side by side like this helps to really bring home the fact that there might be an issue.

It might also be good to see where our ArticlesController sits compared to other controllers, as far as their maximum response time goes, this is a job for a table. We add another chart just like before, but this time pick table instead of chart. To create tables with multiple rows, we need to use wildcards in our metric name. In our case, I will set the metric to be Controller/, this will select all the metrics under the *Controller prefix, I will now set the limit text-box to be 10 which will do exactly as you expect and set the number of rows in our table to ten. In the end, we should have something that looks like this, right before we save:

14_table

Our custom dashboard will now be:

15_custom_dashboard_with_table

It seems that ArticlesController#show has the longest maximum response time out of all the controller actions, including TutorialsController#show, this is very curious and I should probably make a note to look into this.

We can continue adding a bunch of other charts such as end user average response time or calls per minute. However, some things you just can’t construct using a custom chart, such as historical throughput or response time. Luckily we can always fall back on finding the charts that we want somewhere else in New Relic and simply adding those ones to our custom dashboard.

The only limitation with using a dashboard which has custom charts is that you have to have the correct app selected within New Relic, otherwise all the custom charts on your dashboard will be blank.


Creating Dashboards for Your Custom Metrics

If you read my last article on custom metrics, you might remember me mentioning that the only way for you to view the custom metric data that you’ve collected is to create a custom dashboard in New Relic, this is the third reason to use custom dashboards. If you collect a lot of custom metrics, this might be the best reason of all.

On Tuts+ we have a concept of categories (yet again, obviously), I just happen to know that we have a few custom metrics floating around for categories. Let’s see if we can put these on a dashboard and actually get an idea of what’s happening. We’ll create another dashboard and call it ‘Categories Custom Metrics’. All custom metrics in New Relic should live under the Custom prefix and this is where we find the metrics we’re looking for:

16_custom_metrics

We’ll create a couple of charts, one to see how long building presenters in CategoriesController takes and the other to see how long it takes to get a link hash from the presenters. The key thing to know with custom metrics, is what kind of data you’re actually sending to New Relic. In this case I happen to know that we’re measuring time, so I can pick ‘Average value‘ as my metric value and set the Number format to milliseconds to get a reasonable looking chart. After creating both charts, our custom dashboard looks like this:

17_dashboard_for_custom_metrics

It looks like getting the link hash from the presenters is very quick and doesn’t fluctuate too much, there is no need to optimize anything here and I can probably stop collecting this metric completely (no need to capture unnecessary data). However, building the presenters takes significantly more time, we can look into this further to see if it can be optimized. We can also keep an eye on the chart (by looking at the custom dashboard occasionally) to make sure the performance doesn’t degrade as we continue to work on the application.


Conclusion

Custom dashboards are not a panacea. Aside from creating charts for custom metrics, you can do everything that custom dashboards can do with the regular New Relic UI. However playing with custom dashboards will definitely help you become more of a power user of New Relic, with a deeper understanding of how it works under the hood. In addition, the ability to look at your performance metrics in different ways can be an invaluable tool to help you surface potential performance problems before they have a significant impact on your application.

If you have any questions about New Relic custom dashboards, don’t be afraid to leave a comment and I’ll do my best to answer. Also, if you’ve used custom dashboards to good effect in the past, please share any tips you might have, it’s always interesting to see how other people use their tools.

January 21 2014

19:50

Working With LESS and the Chrome DevTools

This is a complete tutorial to using LESS with Chrome’s DevTools. If you’ve already used Sass with Chrome’s DevTools, you’ll most likely already be familiar with the concepts introduced here.

The Tl;dr

  • LESS has very recently added support for Source Maps, so this is new and exciting!
  • DevTools mapping means you can view LESS styles for all your relevant CSS.
  • Edit LESS source files within DevTools and have them save to disk.
  • Source Map adoption is improving with Sass, CoffeeScript, UglifyJS2 and more.

Introduction

Not too long ago, the Chrome DevTools added a number of IDE-like features (and continues to do so), one of which is the ability to understand the mapping between a compiled file and its corresponding source file. This is made possible thanks to Source Maps.

image_0-2

What This Tutorial Will Cover

  • How to generate Source Maps from LESS files.
  • Debugging LESS code through the DevTools.
  • Authoring LESS code in the DevTools and seeing changes immediately via Workspaces and Grunt.

Everything mentioned here is available in Chrome Canary.


Configuring LESS for Source Maps

First thing’s first, install the latest (1.5.1 at the time of this writing) version of LESS through NPM (Source Maps arrived in 1.5.0):

$ npm install -g less
$ lessc -v
lessc 1.5.1 (LESS Compiler) [JavaScript]
image_1

At this point, you can run the LESS compiler in your terminal using the lessc command.

image_2

Create a new LESS file, for demonstration purposes, it’ll be kept short and simple.

@color: #4D926F;
#header {
  color: @color;
}

To turn the LESS file into a CSS file, it’s a simple case of running:

lessc header.less header.css
image_3

We now need a Source Map file. Create it with the -source-map flag.

lessc --source-map=header.map header.less header.css

Using the LESS code shown above, running this command produces a Source Map file with the following contents:

{"version":3,"file":"header.css","sources":["header.less"],"names":[],"mappings":"AAEQ;EACP,cAAA"}

Using DevTools to Map to LESS Source Files

In a world without Source Maps, DevTools would display styles originating from the compiled CSS. Line numbering would not be useful due to a mismatch between compiled CSS and the source CSS. With Source Maps, when inspecting a DOM node on the page, DevTools will automatically show the styles originating from the LESS source file.

Viewing a web page which references the previously mentioned header.css is now inspectable in a more meaningful way.

image_4

While holding Command (Ctrl on Windows), click any property, value or selector to jump to the line of code in the corresponding LESS source file within the Sources Panel.


Authoring Workflow With DevTools & LESS

Viewing LESS code in the DevTools is certainly useful, but integrating an authoring workflow can speed up your iteration cycle. The next step is to tell DevTools how the resources on a web page map to files on a file system. Enter: Workspaces.

Note: Workspaces are suitable for many projects, not just those using CSS preprocessors.

Workspaces

You might already be familiar with the Sources panel from an editing perspective. The general idea is that you have a file navigator in the sidebar where each file is typically a stylesheet, script or HTML resource that the web page has loaded.

image_6

Clicking on a resource displays the contents in the main panel, you may notice the similarity this has with the Resources panel, however there is at least one major difference: the Sources panel contains a live editor. Changes you make to stylesheets are applied to the page instantly and changes you make to scripts are injected back into the V8 engine and evaluated immediately. Not only does this work for remotely hosted files, but also for local ones with the added benefit of persisting your changes to a file.

Note: To make use of Workspaces, the following steps are only required once per project.

Step 1.

Open up a local webpage and add its corresponding folder on your file system to the workspace by Right-Clicking in the Sources panel sidebar and selecting Add folder to Workspace.

image_7

Step 2.

Allow DevTools access to the folder you’ve just added.

image_8

Step 3.

Your newly added folder will appear in the sidebar navigation.

image_9

Right-click on a file within a network resourced folder in the Sources Panel (make sure it has an obvious mapping to a file on your file system) and select Map to File System Resource.

image_10

Step 4.

The first suggestion provided by DevTools is the correct one. It has noticed that the file on my file system (/Users/.../bootstrap.css) has the same name as a network resource file (http://localhost/.../bootstrap.css). Verify the mapping by selecting the correct resource.

image_11

DevTools now understands the mapping between filesystem resources and network resources. When you Cmd/Ctrl-Click a selector from the Styles pane and end in the Sources Panel, you’re now being shown your actual LESS source file. You can edit a file in the Sources panel and those changes will persist to disk when you Command/Control+S.

We’ve come all this way, so let’s complete this workflow by using a Grunt watch task to watch for changes made to the LESS files and then automatically compile our CSS and make a corresponding Source Map file.

Using Grunt to Watch & Compile LESS

With Workspaces set up, configure Grunt (or another tool of your choice) to watch for changes to LESS source files and compile a new CSS file (with a Source Map). DevTools will pick up this change automatically and apply any new styles to the page.

Note: Enable the Auto-reload generated CSS flag in the Settings panel to use this workflow.

image_12

Here is an outline of the automated steps which will occur:

  1. You save a change to a LESS file via DevTools.
  2. A watch task monitors LESS files for changes and then runs a LESS task.
  3. The LESS task compiles a new CSS file plus a Source Map file.
  4. DevTools injects the new CSS file onto the current page without a page refresh.

Here’s a simplified Gruntfile:

module.exports = function(grunt) {
    'use strict';

    require('matchdep').filterDev('grunt-!(cli)').forEach(grunt.loadNpmTasks);

    grunt.initConfig({
        less: {
            dev: {
                options: {
                    sourceMap: true,
                    sourceMapFilename: 'bootstrap.map'
                },
                files: {
                    'less/bootstrap.css': 'less/bootstrap.less'
                }
            }
        },
        watch: {
            all: {
                files: ['less/**/*.less'],
                tasks: ['less'],
            }
        }
    });

    grunt.registerTask('default', ['less', 'watch']);
};

Note: The code snippet above comes from the demo repository.

After an npm install, running grunt in your terminal should show a watch task running.

image_13

DevTools already has write access to your development folder (through Workspaces). Cmd/Ctrl+S your changes in the Sources Panel to have DevTools overwrite the source LESS file with your new change, Grunt compiles a new CSS file which DevTools pulls in and applies to the page.


Conclusion

  • During development and debugging, looking at your source file (rather than the compiled file) will almost always be more useful to you.
  • For DevTools to understand source file mappings, it needs to be compatible with the Source Map v3 proposal which is up to the compilation tool to implement.
  • Tools adopting Source Maps are improving, we have Sass, Compass, LESS, autoprefixer, UglifyJS2, CoffeeScript and more. There are grunt-contrib-* tasks for most of these tools (Sass, Compass, LESS, autoprefixr, UglifyJS2, CoffeeScript) which tie in nicely with a livereload workflow.
  • Viewing LESS files will work out of the box with DevTools. To actually edit files, try out Workspaces which gives you the ability to persist changes to disk.

Further Reading

Source Maps

LESS

Chrome DevTools

Sponsored post
soup-sponsored
05:36
Reposted bySchrammelhammelMrCoffeinmybetterworldkonikonikonikonikoniambassadorofdumbgroeschtlNaitliszpikkumyygittimmoejeschge

January 13 2014

19:13

Browser Testing in the Cloud Redux

I’ve written quite a bit about browser testing solutions trying to help identify techniques and tools that make cross-browser development easier. My last article on the subject covered how to use BrowserStack to test any number of browsers all from one central tool; your own browser.

I was on a Windows PC back then so testing multiple browsers was a bit easier and testing tools were mainly complementary to my work. Now that I’m on OS X, the need for tools to round out my testing strategies is even more important, specifically because of the lack of Internet Explorer on the OS.

I’m a bit of a stickler for what I install on my computers and I prefer online tools when available. I’m also always on the hunt for new tools that make cross-browser testing easier and decided to give CrossBrowserTesting.com a run. I’ll go over some of the key features of the service and how to leverage it to improve your testing capabilities.


ZOMG That’s a Lot of Browsers

First, let’s mention that like every reliable service in this space, CrossBrowserTesting.com charges a monthly fee. I’m not surprised at all by this because the bottom line is that they have an infrastructure to support and well, that costs money. Their fee structure is based on the number of minutes you’d like available to you on a monthly basis but with a unique twist in that they allow you to roll over a certain number of minutes, month to month. So if you don’t use all of your minutes, you can roll some over for the next month.

Onto the service itself. There are a couple of things that are important to me in these types of services. These are:

  • Breadth of browser support across major OS versions
  • Mobile support (as I’m starting to shift to mobile web)
  • Debugging tool support
  • Responsiveness of the UI
  • Form factor support
  • Local system testing support (for example: proxy-based debugging)

All of these matter because they provide you the broadest testing surface across multiple devices. But to be honest, without debugging tool support (like Chrome DevTools, IE F12 Tools, etc.), a service like this would be compelling to use and only marginally better than a screenshot service. And being able to test locally is an obvious must-have to allow you to test interactively before deploying to staging or production. So this criteria is important to consider.

The first thing I noticed about the service is its amazing breadth of browser and device form factor support. Every major OS is covered (including Ubuntu) and every OS version has a fairly comprehensive list of supported browser versions for testing.

win8

In addition, there’s extensive support for mobile devices and browsers covering earlier and more modern versions of Android, iOS, Blackberry Bold and Windows Phone 8. The interesting (and really beneficial) thing is that for specific Android versions, they’re allowing you to test against competing browsers like Firefox Mobile, Maxthon and Opera.


Testing With the Service

If you’ve used BrowserStack or a similar service, you’ll feel right at home in CrossBrowserTesting.com. The user experience matches very closely to what I’ve seen before which made jumping into it fairly trivial. You’re initially presented with a dashboard that gives you access to the main features. These include:

  • Live browser testing
  • Automated screenshot service
  • Establishing a local connection

The live browser testing is what I’m most interested in. For me, I need to ensure that the rendering is consistent so the first thing I did was to do a baseline test to see if a site will render the same in my virtual browser as it does in my local browser. To mimic my local settings I chose to start the session in Mavericks, running under the most recent stable version of Chrome:

gnc-baseline

One thing to note is that in the OS/browser selection form, you’re solely presented with the browser options available for that specific OS version like this:

gnc-browser-options

I went with GNC’s website because, well, I’m a bit of a fitness buff and they have a lot of interactive points as well, such as JavaScript-based fly-over menus and cycling feature panels. I figured it was a good test to see if the service could handle all of the interaction.

Looking at the two screenshots, you can see that the rendering for Chrome on Mavericks on both systems is exactly the same. This is a good thing, although it’s a bit trippy to see Chrome on Mavericks within Chrome on Mavericks. Inception anyone?

gnc-real

Local machine

gnc-cbt

Remote virtual browser

Once your session is running, you can change your target OS and browser version at any time by clicking on the Change Configuration button which displays the panel with dropdown choices. Note that changing the OS or browser will reload your session but it sure beats having to spark up multiple virtual machines, especially for cursory reviews of pages.

Getting the baseline UI was great but a more important test is to see how the site responds to interaction. Let me preface this by saying that I’ve not found a service like this that offers instantaneous response. There will always be a lag because these browsers are virtualized. The key thing that you want is to ensure that normal interaction, like hovering over a menu or controlling UI controls (like a scrolling panel) performs as expected (albeit a little slower). For example, GNC’s site has a dropdown menu system that expands when you hover over a menu option. Notice that hovering over it will expand the menu and equally important give me the option to drill-down into it.

gnc-menu

This interactivity is what makes these services so valuable. The days of having to rely on screenshot services and a ton of VMs to see how your site renders across a ton of browsers are gone.


What About Debugging?

Good question. Browser-based developer tools have really progressed nicely and we depend on them daily. Thankfully, CrossBrowserTesting.com has included the default debugging tools with each browser giving us access to Chrome DevTools, the IE F12 Developer Tools, and Firefox’s Web Developer Tools as well as Firebug for older versions of the browser. Notice here that I’ve fired up the IE F12 tools in IE11 on Windows 7.

gnc-debug

The tools are completely functional allowing me to inspect the markup and DOM structure of the page as well as set styles and change text, just like you would on your local PC. You can see here how I’m able to update the inline JavaScript on the site:

gnc-debug-2

What this translates to is the ability to leverage the debuggers to do advanced debugging work like script debugging across any browser and browser version.

One thing I was concerned about is whether the tools would accurately show page load times via the network traffic monitoring panels and in my tests, they seem to be consistent with what I saw locally. This means I can feel confident, to some degree, that the load times will be more or less on par (of course taking into account network issues).

The one thing that I think would be very hard to measure, though, is page performance via the new suite of performance profilers included in Chrome and Internet Explorer. A lot of that data is directly affected by aspects of your computer, especially when rendering is GPU-enhanced. Testing this on virtualized browsers or virtual machines just isn’t real-world so I wouldn’t recommend it. If you’re an interactive developer (games), then it’s best to test on your own device to get a better understanding of performance.


Testing Different Form Factors

As I begin focusing on mobile more and more, the need to test across multiple mobile OSs and different form factors becomes a high priority. Unfortunately, short of getting a very big inheritance, winning the lotto, or finding a loving sponsor, building a full-featured mobile device lab just isn’t in the cards. And at the pace things are going, things are only get tougher as manufacturers continue to push the limits of mobile browsers and device size.

CrossBrowserTesting.com offers the ability to test across the major mobile OSs simulating most of the popular mobile devices like iPads, iPhones, Nexus 7s and such. This is certainly not an all-encompassing list of mobile devices and I’m assuming is meant to tackle the most modern OSs and devices available.

The process to testing is exactly the same as what we did for desktop browsers, except the rendering will be within the size of the specific mobile device you’ve selected:

gnc-iphone

Again, the service uses simulators to allow you to test out how your site will render on a mobile device. Keep in mind, though, that while simulators are good it’s always best to test against a real device if possible.

New devices come out all the time and I wouldn’t expect every form factor to be on here. I think a nice addition would be to allow a user of the service to be able to define the viewport size as opposed to solely being presented default screen resolutions. This would also offer more flexibility in testing sites that are responsive.


Screenshots

Before interactive services like CrossBrowserTesting.com became available, screenshot services became known as one of the quickest ways of seeing how your site rendered across multiple browsers. While they’re kind of passe now, they’re still useful and interestingly enough, I’m seeing most of these browser testing services spin up screenshot capture as part of their offerings. So it seems this practice is having a bit of a renaissance, most likely driven by the increasing number of browser versions, devices and form factors we need to account for.

Using the service is straightforward and as easy as entering a URL, selecting the browsers you’d like screenshots from, and clicking the Take Screenshots button:

screenshot

The nice thing about this is that it allows you to choose as many device/OS/browser combinations as you’d like as well as define the resolution on a per-target basis. This generates a series of snapshots that you can review:

screenshot-gnc

Clicking individual screenshots displays a larger image allowing you to get a detailed view of the rendering.

A couple of things to keep in mind: It takes a little while for the screenshots to be captured and rendered. So the more browsers you select, the longer you’ll wait. Unlike other services where you wait your turn in a queue, this wait seems to be simply associated with processing time. You’re paying for the service so I can’t imagine there being a queue like BrowserShots.org. Also bear in mind that some of these screenshots are invariably derived from simulators and as I mentioned before, simulators don’t always render the same as a real browser. Lastly, the screenshot is for a specific page, not the entire site.

Nonetheless, the fact that I can fairly quickly get an idea of how my site is rendering across so many devices helps me to drill-down into specific browser combinations that need special attention.

And that’s where a really neat feature comes in. The service offers the ability to compare layouts side-by-side so you can see rendering differences between different browsers:

screenshot-compare

As you can see in the screenshot, it goes a step further by also detailing the differences and creating a transparent yellow overlay on each panel to highlight the actual differences. I’m sure you can relate to the frustration many a developer has felt over discovering slight layout differences after the fact. This helps to bring that forward during the testing process. And you can scroll through and compare multiple scenarios by clicking the Prev and Next buttons.


Testing Local Files Remotely

The true value of a service like this is to facilitate your local debugging efforts. Simply allowing you to test publicly-available sites offers such limited value in terms of your overall testing strategy. CrossBrowserTesting.com provides the ability to test your local files against their remote servers using a Java-based proxy applet or the command line, again leveraging Java to create a proxy. This is similar to other services and is necessary to establish the connection between your local PC and the remote servers as well as allowing you to be able to tunnel past any firewalls you might have in your company. Once the connection is set, you’re able to test out both local files via direct access or via URL from your local web server.

The team at CrossBrowserTesting.com have created a video which gives you a good explanation and demonstration of how this part of the service works.


Closing Thoughts

It’d be truly great if we didn’t need these services. That would mean every browser rendered totally as expected across every device that supported them. Unfortunately, we still have a bit of browser fragmentation and every browser version tends to have their own quirks to contend with. So services like CrossBrowserTesting.com provide real value in streamlining cross-browser testing.

Overall, I think the service is very good albeit not without some quirks of its own. There were some intermittent lockups that I experienced in the live testing which may be attributed to Flash and in some sessions, seeing a number of browser icons in the OS dock left me scratching my head as to why they were there when I chose a specific target browser. These issues didn’t necessarily prevent me from doing what I wanted to do (testing) but it felt like things needed to be tidied up a bit.

The layout comparison feature, though, was pretty hot and something I could see myself using regularly.

What I am seeing is that price could be a big success factor for the breadth of services they’re offering. CrossBrowserTesting.com appears to have set themselves at a very competitive price point incorporating live testing, screenshots and local testing into one fixed monthly cost as opposed to separate pricing for specific services. This is very appealing, especially for price-conscious developers.

The big factor, though, will be how much time you need for testing. From experience, two and a half hours (the amount of time allotted for the Basic plan) seems a little limited especially when accounting for latency of rendering. Again, your mileage may vary but it’s certainly something to consider.

January 03 2014

19:46

Testing in Node.js

A test driven development cycle simplifies the thought process of writing code, makes it easier, and quicker in the long run. But just writing tests is not enough by itself, knowing the kinds of tests to write and how to structure code to conform to this pattern is what it's all about. In this article we will take a look at building a small app in Node.js following a TDD pattern.

Besides simple 'unit' tests, which we are all familiar with; We can also have Node.js's Async code running, which adds an extra dimension in that we don't always know the order in which functions will run or we may be trying to test something in a callback or checking to see how an async function is working.

In this article we will be building a Node app which can search for files that match a given query. I know there are already things for this (ack) but for the sake of demonstrating TDD I think it could be a well rounded project.

The first step is obviously to write some tests, but even before that, we need to choose a testing framework. You can use vanilla Node, as there is an assert library built-in, but it's not much in terms of a test runner, and is pretty much the bare essentials.

Another option and probably my favorite for general use is Jasmine. It's pretty self-contained, you don't have any other dependencies to add to your scripts and the syntax is very clean and easy to read. The only reason I am not going to use this today, is because I think Jack Franklin did an excellent job covering this in his recent Tuts+ series here, and it's good to know your options so you can pick the best tool for your situation.


What We’ll Be Building

In this article we will be using the flexible 'Mocha' test runner along with the Chai assertion library.

Unlike Jasmine which is more like an entire test suite in one package, Mocha only takes care of the overall structure but has nothing to do with the actual assertions. This allows you to keep a consistent look and feel when running your tests, but also allows you to run whichever assertion library best fits your situation.

So for example, if you were going to use the vanilla 'assert' library, you could pair it with Mocha to add some structure to your tests.

Chai is a fairly popular option, and is also all about options and modularity. Even without any plugins, just using the default API you have three different syntaxes you can use depending on if you would like to use a more classic TDD style or a more verbose BDD syntax.

So now that we know what we are going to use, let's get into the installation.


The Setup

To get started, let's install Mocha globally by running:

npm install -g mocha

When that completes create a new folder for our project and run the following inside it:

npm install chai

This will install a local copy of Chai for our project. Next, create a folder named test inside our project's directory, as this is the default location Mocha will look for tests.

That's pretty much it for setup, the next step is to talk about how to structure your apps when following a test driven development process.


Structuring Your App

It's important to know, when following a TDD approach, what needs to have tests and what does not. A rule of thumb is to not write tests for other peoples already tested code. What I mean by this is the following: let's say your code opens a file, you don't need to test the individual fs function, it's part of the languge and is supposedly already well tested. The same goes when using third-party libraries, you shouldn't structure functions which primarily call these types of functions. You don't really write tests for these and because of this you have gaps in the TDD cycle.

Now of course, with every programming style there are a lot of different opinions and people will have different views on how to TDD. But the approach I use is that you create individual components to use in your app, each of which solves a unique functional problem. These components are built using TDD ensuring that they work as expected and you won't break their API. Then you write your main script, which is essentially all glue code, and does not need to be tested / can't be tested, in certain situations.

This also means that most of your components can be reused in the future as they do not really have much to do, directly, with the main script.

Following what I just said, it's common practice to create a folder named 'lib' where you put all the individual components. So up to this point you should have Mocha and Chai installed, and then a project directory with two folders: 'lib' and 'test'.


Getting Started With TDD

Just in case you are new to TDD I thought it would be a good idea to quickly cover the process. The basic rule is that you can't write any code unless the test runner tells you to.

Essentially, you’re writing what your code is supposed to do before actually doing it. You have a really focused goal while coding and you never compromise your idea by getting side-tracked or thinking too far ahead. Besides that, since all of your code will have a test affiliated with it you can be certain you will never break your app in the future.

A test, in reality, is just a declaration of what a function is expected to do when run, you then run your test runner, which will obviously fail (since you haven't written the code yet) and then you write the minimum amount of code needed to pass the failing test. It's important never to skip this step, because sometimes a test will pass even before you add any code, due to other code you have in the same class or function. When this happens, you either wrote more code then you were supposed to for a different test or this is just a bad test (usually not specific enough).

Again according to our rule above, if the test passes right away you can't write any code, because it didn't tell you to. By continuously writing tests and then implementing the features you construct solid modules that you can rely on.

Once you’re finished implementing and testing your component, you can then go back and refactor the code to optimize it and clean it up but making sure the refactoring doesn't fail any of the tests you have in place and more importantly, doesn't add any features that are untested.

Every testing library will have its own syntax, but they usually follow the same pattern of making assertions and then checking if they pass. Since we are using Mocha and Chai let's take a look at both their syntaxes starting with Chai.


Mocha & Chai

I will be using the 'Expect' BDD syntax, because as I mentioned Chai comes with a few options out of the box. The way this syntax works is you start by calling the expect function, passing it the object you want to make an assertion on, and then you chain it with a specific test. An example of what I mean could be as follows:

expect(4+5).equal(9);

That's the basic syntax, we are saying expect the addition of 4 and 5 to equal 9. Now this isn't a great test because the 4 and 5 will be added by Node.js before the function is even called so we are essentially testing my math skills, but I hope you get the general idea. The other thing you should note, is this syntax is not very readable, in terms of the flow of a normal English sentence. Knowing this, Chai added the following chain getters which don't do anything but you can add them to make it more verbose and readable. The chain getters are as follows:

  • to
  • be
  • been
  • is
  • that
  • and
  • have
  • with
  • at
  • of
  • same
  • a
  • an

Using the above, we can rewrite our previous test to something like this:

expect(4+5).to.equal(9);

I really like the feel of the entire library, which you can check out in their API. Simple things like negating the operation is as easy as writing .not before the test:

expect(4+5).to.not.equal(10);

So even if you have never used the library before, it won't be hard to figure out what a test is trying to do.

The last thing I would like to look over before we get into our first test is how we structure our code in Mocha

Mocha

Mocha is the test runner, so it doesn't really care too much about the actual tests, what it cares about is the tests structure, because that is how it knows what is failing and how to layout the results. The way you build it up, is you create multiple describe blocks which outline the different components of your library and then you add it blocks to specify a specific test.

For a quick example, let's say we had a JSON class and that class had a function to parse JSON and we wanted to make sure the parse function can detect a badly formatted JSON string, we could structure this like so:

describe("JSON", function() {
   describe(".parse()", function() {
       it("should detect malformed JSON strings", function(){
           //Test Goes Here
       });
   });
});

It's not complicated, and it's about 80% personal preference, but if you keep this kind of format, the test results should come out in a very readable format.

We are now ready to write our first library, let's begin with a simple synchronous module, to get ourselves better acquainted with the system. Our app will need to be able to accept command line options for setting things like how many levels of folders our app should search through and the query itself.

To take care of all this, we will create a module which accepts the command's string and parses all the included options along with their values.

The Tag Module

This is a great example of a module you can reuse in all your command line apps, as this issue comes up a lot. This will be a simplified version of an actual package I have on npm called ClTags. So to get started, create a file named tags.js inside of the lib folder, and then another file named tagsSpec.js inside of the test folder.

We need to pull in the Chai expect function, as that will be the assertion syntax we will be using and we need to pull in the actual tags file so we can test it. Altogether with some initial setup it should look something like this:

var expect = require("chai").expect;
var tags = require("../lib/tags.js");

describe("Tags", function(){

});

If you run the 'mocha' command now from the root of our project, everything should be passing like expected. Now let's think about what our module will do; we want to pass it the command arguments array that was used to run the app, and then we want it to build an object with all the tags, and it would be nice if we could also pass it a default object of settings, so if nothing get's overridden, we will have some settings already stored.

When dealing with tags, a lot of apps also provide shortcut options which are just one character, so let's say we wanted to set the depth of our search we could allow the user to either specify something like --depth=2 or something like -d=2 which should have the same effect.

So let's just begin with the long formed tags (for example, '–depth=2'), To begin with, let's write the first test:

describe("Tags", function(){
   describe("#parse()", function(){
       it("should parse long formed tags", function(){
           var args = ["--depth=4", "--hello=world"];
           var results = tags.parse(args);

           expect(results).to.have.a.property("depth", 4);
           expect(results).to.have.a.property("hello", "world");
       });
   });
});

We added one method to our test suite called parse and we added a test for long formed tags. Inside this test I created an example command and added two assertions for the two properties it should pickup.

Running Mocha now, you should get one error, namely that tags doesn't have a parse function. So to fix this error let's add a parse function to the tags module. A fairly typical way to create a node module is like so:

exports = module.exports = {};

exports.parse = function() {

}

The error said we needed a parse method so we created it, we didn't add any other code inside because it didn't yet tell us to. By sticking with the bare minimum you are assured that you won't write more then you are supposed to and end up with untested code.

Now let's run Mocha again, this time we should be getting an error telling us that it can't read a property named depth from an undefined variable. That is because currently our parse function isn't returning anything, so let's add some code so that it will return an object:

exports.parse = function() {
var options = {}

return options;
}

We are slowly moving along, if you run Mocha again, their shouldn't be any exceptions being thrown, just a clean error message saying that our empty object has no property called depth.

No 'depth' property

Now we can get into some real code. For our function to parse the tag and add it to our object we need to cycle through the arguments array and remove the double dashes at the start of the key.

exports.parse = function(args) {
   var options = {}
   for (var i in args) { //Cycle through args
       var arg = args[i];
       //Check if Long formed tag
       if (arg.substr(0, 2) === "--") {
           arg = arg.substr(2);
           //Check for equals sign
           if (arg.indexOf("=") !== -1) {
               arg = arg.split("=");
               var key = arg.shift();
               options[key] = arg.join("=");
           }
       }
   }
   return options;
}

This code cycles through the list of arguments, makes sure we are dealing with a long formed tag, and then splits it by the first equals character to create the key and value pair for the options object.

Now this almost solves our issue, but if we run Mocha again, you will see that we now have a key for depth, but it's set to a string instead of a number. Numbers are a bit easier to work with later on in our app, so the next piece of code we need to add is to convert values to numbers whenever possible. This can be achieved with some RegEx and the parseInt function as follows:

        if (arg.indexOf("=") !== -1) {
            arg = arg.split("=");
            var key = arg.shift();
            var value = arg.join("=");

            if (/^[0-9]+$/.test(value)) {
                value = parseInt(value, 10);
            }
            options[key] = value;
        }

Running Mocha now, you should get a pass with one test. The number conversion should arguably be in its own test, or at least mentioned in the tests declaration so you don't, by mistake, remove the number conversion assertion; so just add-on “add and convert numbers” to the it declaration for this test or separate it into a new it block. It really depends whether you consider this “obvious default behavior” or a separate feature.

First Pass

Now like I have been trying to stress throughout this whole article, when you see a passing spec, it's time to write more tests. The next thing I wanted to add was the default array, so inside the tagsSpec file let's add the following it block right after the previous one:

    it("should parse long formed tags and convert numbers", function(){
        var args = ["--depth=4", "--hello=world"];
        var results = tags.parse(args);

        expect(results).to.have.a.property("depth", 4);
        expect(results).to.have.a.property("hello", "world");
    });
    it("should fallback to defaults", function(){
        var args = ["--depth=4", "--hello=world"];
        var defaults = { depth: 2, foo: "bar" };
        var results = tags.parse(args, defaults);

        var expected = {
            depth: 4,
            foo: "bar",
            hello: "world"
        };

        expect(results).to.deep.equal(expected);
    });

Here we are using a new test, the deep equal which is good for matching two objects for equal values. Alternatively, you can use the eql test which is a shortcut but I think this is more clear. This test passes two arguments as the command string and passes two defaults with one overlap, just so we can get a good spread on the test cases.

Running Mocha now, you should get a sort of diff, containing the differences between what is expected and what it actually got.

Defaults Diff

Let's now continue back to the tags.js module, and let's add this functionality in. It's a fairly simple fix to add, we just need to accept the second parameter, and when it's set to an object we can replace the standard empty object at the start with this object:

exports.parse = function(args, defaults) {
   var options = {};
   if (typeof defaults === "object" && !(defaults instanceof Array)) {
       options = defaults
   }

This will bring us back to a green state. The next thing I want to add is the ability to just specify a tag without a value and let it work like a boolean. For example, if we just set --searchContents or something like that, it will just add that to our options array with a value of true.

The test for this would look something like the following:

   it("should accept tags without values as a bool", function(){
       var args = ["--searchContents"];
       var results = tags.parse(args);

       expect(results).to.have.a.property("searchContents", true);
   });

Running this will give us the following error just like before:

Boolean Tags

Inside of the for loop, when we got a match for a long formed tag, we checked if it contained an equals sign; we can quickly write the code for this test by adding an else clause to that if statement and just setting the value to true:

        if (arg.indexOf("=") !== -1) {
             arg = arg.split("=");
             var key = arg.shift();
             var value = arg.join("=");

             if (/^[0-9]+$/.test(value)) {
                 value = parseInt(value, 10);
             }
             options[key] = value;
        } else {
             options[arg] = true;
        }

The next thing I want to add is the substitutions for the short-hand tags. This will be the third parameter to the parse function and will basically be an object with letters and their corresponding replacements. Here is the spec for this addition:

    it("should accept short formed tags", function(){
        var args = ["-sd=4", "-h"];
        var replacements = {
            s: "searchContents",
            d: "depth",
            h: "hello"
        };

        var results = tags.parse(args, {}, replacements);

        var expected = {
            searchContents: true,
            depth: 4,
            hello: true
        };

        expect(results).to.deep.equal(expected);
    });

The trouble with shorthand tags is that they are able to be combined in a row. What I mean by this is unlike the long formed tags where each one is separate, with short hand tags – since they are each just a letter long – you can call three different ones by typing -vgh. This makes the parsing a bit more difficult because we still need to allow for the equals operator for you to add a value to the last tag mentioned, while at the same time you need to still register the other tags. But not to worry, it's nothing that can't be solved with enough popping and shifting.

Here is the entire fix, from the beginning of the parse function:

exports.parse = function(args, defaults, replacements) {
   var options = {};
   if (typeof defaults === "object" && !(defaults instanceof Array)) {
       options = defaults
   }

   if (typeof replacements === "object" && !(defaults instanceof Array)) {
        for (var i in args) {
             var arg = args[i];
             if (arg.charAt(0) === "-" && arg.charAt(1) != "-") {
                  arg = arg.substr(1);
                  if (arg.indexOf("=") !== -1) {
                      arg = arg.split("=");
                      var keys = arg.shift();
                      var value = arg.join("=");

                      arg = keys.split("");
                      var key = arg.pop();
                      if (replacements.hasOwnProperty(key)) {
                           key = replacements[key];
                      }

                      args.push("--" + key + "=" + value);
                  } else {
                      arg = arg.split("");
                  }

                  arg.forEach(function(key){
                      if (replacements.hasOwnProperty(key)) {
                          key = replacements[key];
                      }
                      args.push("--" + key);
                  });
             }
        }
   }

It's a lot of code (in comparison) but all we are really doing is splitting the argument by an equals sign, then splitting that key into the individual letters. So for example if we passed -gj=asd we would split the asd into a variable called value, and then we would split the gj section into individual characters. The last character (j in our example) will become the key for the value (asd) whereas any other letters before it, will just be added as regular boolean tags. I didn't want to just process these tags now, just in case we changed the implementation later. So what we are doing is just converting these short hand tags into the long formed version and then letting our script handle it later.

Running Mocha again will take us back to our illustrious green results of four tests passing for this module.

Now there are a few more things we can add to this tags module to make it closer to the npm package, like the ability to also store plain text arguments for things like commands or the ability to collect all the text at the end, for a query property. But this article is already getting long and I would like to move on to implementing the search functionality.


The Search Module

We just went through creating a module step by step following a TDD approach and I hope you got the idea and feeling of how to write like this. But for the sake of keeping this article moving, for the rest of the article, I will speed up the testing process by grouping things together and just showing you the final versions of tests. It's more of a guide to different situations which may come up and how to write tests for them.

So just create a file named search.js inside the lib folder and a searchSpec.js file inside of the test folder.

Next open the spec file and let's setup our first test which can be for the function to get a list of files based on a depth parameter, this is also a great example for tests which require a bit of external setup for them to work. When dealing with outside object-like-data or in our case files, you will want to have a predefined setup which you know will work with your tests, but you also don't want to add fake info to your system.

There are basically two options to solve this problem, you can either mock the data, like I mentioned above if you are dealing with the languages own commands for loading data, you don't necessarily need to test them. In cases like that, you can simply provide the 'retrieved' data and continue on with your testing, kind of like what we did with the command string in the tags library. But in this case, we are testing the recursive functionality we are adding to the languages file reading capabilities, depending on the specified depth. In cases like these, you do need to write a test and so we need to create some demo files to test the file reading. The alternative is to maybe stub the fs functions to just run but not do anything, and then we can count how many times our fake function ran or something like that (check out spies) but for our example, I am just going to create some files.

Mocha provides functions which can run both before and after your tests, so you can perform these kinds of external setup and cleanup around your tests.

For our example, we will create a couple of test files and folders at two different depths so we can test out that functionality:

var expect = require("chai").expect;
var search = require("../lib/search.js");
var fs = require("fs");

describe("Search", function(){
   describe("#scan()", function(){
       before(function() {
           if (!fs.existsSync(".test_files")) {
               fs.mkdirSync(".test_files");
               fs.writeFileSync(".test_files/a", "");
               fs.writeFileSync(".test_files/b", "");
               fs.mkdirSync(".test_files/dir");
               fs.writeFileSync(".test_files/dir/c", "");
               fs.mkdirSync(".test_files/dir2");
               fs.writeFileSync(".test_files/dir2/d", "");
           }
       });

       after(function() {
           fs.unlinkSync(".test_files/dir/c");
           fs.rmdirSync(".test_files/dir");
           fs.unlinkSync(".test_files/dir2/d");
           fs.rmdirSync(".test_files/dir2");
           fs.unlinkSync(".test_files/a");
           fs.unlinkSync(".test_files/b");
           fs.rmdirSync(".test_files");
       });
   });
});

These will be called based on the describe block they are in, and you can even run code before and after each it block using beforeEach or afterEach instead. The functions themselves just use standard node commands to create and remove the files respectively. Next we need to write the actual test. This should go right next to the after function, still inside the describe block:

       it("should retrieve the files from a directory", function(done) {
           search.scan(".test_files", 0, function(err, flist){
               expect(flist).to.deep.equal([
                   ".test_files/a",
                   ".test_files/b",
                   ".test_files/dir/c",
                   ".test_files/dir2/d"
               ]);
               done();
           });
       });

This is our first example of testing an async function, but as you can see it's just as simple as before; all we need to do is use the done function Mocha provides in the it declarations to tell it when we are finished with this test.

Mocha will automatically detect if you specified the done variable in the callback and it will wait for it to be called allowing you to test asynchronous code really easily. Also, it's worth mentioning that this pattern is available throughout Mocha, you can for example, use this in the before or after functions if you needed to setup something asynchronously.

Next I would like to write a test that makes sure the depth parameter works if set:

    it("should stop at a specified depth", function(done) {
        search.scan(".test_files", 1, function(err, flist) {
            expect(flist).to.deep.equal([
                ".test_files/a",
                ".test_files/b",
            ]);
            done();
        });
    });

Nothing different here, just another plain test. Running this in Mocha you will get an error that the search doesn’t have any methods, basically because we haven't written anything in it. So let's go add an outline with the function:

var fs = require("fs");

exports = module.exports = {};

exports.scan = function(dir, depth, done) {

}

If you now run Mocha again, it will pause waiting for this async function to return, but since we haven't called the callback at all, the test will just timeout. By default it should time out after about two seconds, but you can adjust this using this.timeout(milliseconds) inside of a describe or it block, to adjust their timeouts respectively.

This scan function is supposed to take a path and depth, and return a list of all the files it finds. This is actually kind of tricky when you start thinking about how we are essentially recursing two different functions together in a single function. We need to recurse through the different folders and then those folders need to scan themselves and decide on going further.

Doing this synchronously is fine because you can kind of step through it one by one, slowly completing one level or path at a time. When dealing with an async version it get's a bit more complicated because you can't just do a foreach loop or something, because it won't pause in between folders, they will all essentially run at the same time each returning different values and they would sort of overwrite each other.

So to make it work, you need to create a sort of stack where you can asynchronously process one at a time (or all at once if you use a queue instead) and then keep some order in that manner. It's a very specific algorithm so I just keep a snippet by Christopher Jeffrey which you can find on Stack Overflow. It doesn't apply just to loading files, but I have used this in a number of applications, basically anything where you need to process an array of objects one at a time using async functions.

We need to alter it a bit, because we would like to have a depth option, how the depth option works is you set how many levels of folders you want to check, or zero to recurs indefinitely.

Here is the completed function using the snippet:

exports.scan = function(dir, depth, done) {
   depth--;
   var results = [];
   fs.readdir(dir, function(err, list) {
       if (err) return done(err);
       var i = 0;
       (function next() {
           var file = list[i++];
           if (!file) return done(null, results);
           file = dir + '/' + file;
           fs.stat(file, function(err, stat) {
               if (stat && stat.isDirectory()) {
                   if (depth !== 0) {
                       var ndepth = (depth > 1) ? depth-1 : 1;
                       exports.scan(file, ndepth, function(err, res) {
                           results = results.concat(res);
                           next();
                       });
                   } else {
                       next();
                   }
               } else {
                   results.push(file);
                   next();
               }
           });
       })();
   });
};

Mocha should now be passing both tests. The last function we need to implement is the one which will accept an array of paths and a search keyword and return all matches. Here is the test for it:

    describe("#match()", function(){
        it("should find and return matches based on a query", function(){
            var files = ["hello.txt", "world.js", "another.js"];
            var results = search.match(".js", files);
            expect(results).to.deep.equal(["world.js", "another.js"]);

            results = search.match("hello", files);
            expect(results).to.deep.equal(["hello.txt"]);
        });
    });

And last but not least, let's add the function to search.js:

exports.match = function(query, files){
  var matches = [];
  files.forEach(function(name) {
      if (name.indexOf(query) !== -1) {
          matches.push(name);
      }
  });
  return matches;
}

Just to make sure, run Mocha again, you should have a total of seven tests all passing.

All Green!

Putting It All Together

The last step is to really write the glue code which pulls all our modules together; so in the root of our project add a file named app.js or something like that and add the following inside:

# !/usr/bin/env node

var tags = require("./lib/tags.js");
var search = require("./lib/search.js");
var defaults = {
   path: ".",
   query: "",
   depth: 2
}
var replacements = {
   p: "path",
   q: "query",
   d: "depth",
   h: "help"
}

tags = tags.parse(process.argv, defaults, replacements);

if (tags.help) {
   console.log("Usage: ./app.js -q=query [-d=depth] [-p=path]");
} else {
   search.scan(tags.path, tags.depth, function(err, files) {
       search.match(tags.query, files).forEach(function(file){
           console.log(file);
       });
   });
}

No actual logic going on here really, we are just basically connecting the different modules together to get the desired results. I usually don't test this code as it's just glue code which has all been tested already.

You can now make your script executable (chmod +x app.js on a Unix system) and then run it like so:

./app.js -q=".js"

Optionally customizing some of the other placeholders we setup.

Action Still

Conclusion

In this article we have built an entire file searching app, albeit a simple one, but I think it demonstrates the process as a whole fairly well.

Some personal advice moving forward; if you are going to do a lot of TDD, setup your environment. A lot of the overhead time people associate with TDD is due to them having to keep switching windows around, opening and closing different files, then running tests and repeating this 80 dozen times a day. In such a case it interrupts your workflow decreasing productivity. But if you have your editor setup, like you either have the tests and code side-by-side or your IDE supports jumping back and forth, this saves a ton of time. You can also get your tests to automatically run by calling it with the -w tag to watch the files for changes and auto run all tests. These kinds of things make the process more seamless and more of an aid then a bother.

I hope you enjoyed this article, if you have any questions you can leave them below, contact me on Twitter @gabrielmanricks or on the Nettuts+ IRC channel (#nettuts on freenode).

December 19 2013

19:29

Coding in the Cloud

The Internet has allowed us to work anywhere we want, giving us tremendous flexibility in choosing where we'd like to plant ourselves to build the next great app. Not being tied to an office desk has been a blessing to many who cherish the ability to work in varying environments and draw inspiration from their surroundings. But for the most part, we've needed to have a full-blown development machine to make this happen. What if we could leverage the cloud as a development environment itself, freeing us up to choose from a variety of devices to accomplish the same thing. That's what we'll explore in this article.


Coding in the Cloud

As I mentioned, until now, whether you were in an office or sitting at a coffee shop, you generally needed a development machine (a MacBook, Windows, or Linux laptop in most cases) which may have the following things:

  • An editor or IDE like Sublime, Vim or Visual Studio
  • A local web server like MAMP
  • An app server and framework (RoR, Python/Django, Node.js)
  • Git
  • LiveReload or CodeKit

And countless other tools that you rely on to get your work done. This typically requires that you have a beefy machine to work with so you can power all of these tools and be productive.

But with broadband becoming more prevalent, the requirements for having such a powerful device are becoming less stringent due to the number of cloud offerings available to developers. Services like Cloud9 IDE and Nitrous.io are bringing real-world development environments to the cloud and allowing developers to work remotely and offering more flexibility in terms of the devices they choose to work with.

These services not only bring IDEs to the web, they also provide infrastructure that gives developers:

  • Complete Git integration with services like Github and Bitbucket
  • Terminal access for command line functionality
  • Virtualized backends allowing you to spin up instances of RoR or Node.js
  • Deployment to production services like Heroku or Windows Azure
  • Team collaboration

Basically, these services are adding in the kitchen sink, making the move to the cloud much easier and enticing. Let's explore these a little more.


Cloud9 IDE

My first exposure to a real cloud-based IDE was Cloud9. They had a very basic online editor with Github integration which was very cool and obviously very alpha at the time. Nonetheless, it was incredibly promising and along with the work Mozilla was doing on Bespin, it showed tremendous potential. Interestingly enough, the Mozilla Bespin project was later merged into Ace, Cloud9's editor, which seems to have greatly contributed to the solid editing experience in the cloud-based IDE.

C9 takes a very similar pricing approach to Github, offering a nice baseline set of features via a freemium model with more unlimited functionality for $12 per month. The differences boil down to the type of workspaces you have, the number you can have and the features available within those workspaces. A workspace is where your project lives, including your project files and the tools and services you might use (such as Ruby or Python). So depending on how sophisticated your needs are, you may need to seriously consider the premium option which gives you:

  • Five more private workspaces
  • Unlimited FTP workspaces
  • More virtual disk space for your workspaces
  • Full terminal and command line access within your workspaces

The terminal options are especially important since C9 allows you to SSH and FTP into your own server, basically allowing you to use their service as solely a cloud-based IDE.

The fact that they offer a freemium option is great for kicking the tires to see if it's a service you can get into.

You have a couple of options for sign-in, including a traditional email/password scenario or you can use OAuth via GitHub or BitBucket. Doing so with the latter two gives you access to the repositories you already have stored on those services, as evidenced here:

c9-workspace

The workspace allows me to either clone an existing repo from the imported list, clone from a URL of my choice or create a new workspace based off a remote server (via SSH or FTP)

new-workspace

I decided to clone my "authy" Git repo which was the sample source code I wrote for an article here on Nettuts+ on two-factor authentication. The app server I used for that was ColdFusion and I was pretty excited to see the C9 recognized the ColdFusion files correctly. I honestly wasn't expecting it since CFML isn't as popular as it used to be:

ide-authy

Notice that my entire project structure is brought over intact and I have full editing capabilities on my files. In addition, I also have access to full terminal commands:

ide-terminal

To drive this home a bit more, notice in the following screenshot I made a change to gettoken.cfm by adding a comment. Typing in git status in the terminal panel displays the changed status of the file just like you would expect:

ide-terminal-git

Then following up with git commit -a -m "Added comment" and git push updates my repo accordingly:

commit-github

A key feature that the C9 likes to hype is the JavaScript autocomplete capabilities and it makes sense since it's such an invaluable resource in any editor.

c9-autocomplete

I know there's been a lot of debate recently about whether or not autocomplete hinders your ability to remember language features but with the growing level of complexity in libraries, frameworks and tools, I personally find tremendous value in having a little help remembering things. I do wish they offered more language support though.

One of the biggest selling points is the maturity of the documentation. It covers everything about the service from customizing the IDE to integrating with database systems and deploying your code. There are a number of video tutorials that you can leverage to get familiar with the service, which complement the solid documentation.

Lastly, if you're adventurous, you could decide to roll your own version of Cloud9 IDE since it is an open-source project licensed under the GPL. The GitHub page offers good instructions on how to install it, both as *nix and Windows environments, so if you'd like to forego the cost, have at it.


Nitrous.IO

Nitrous.IO (which I'll just refer to as Nitrous from now on) is a new option that's gotten a lot of praise from developers like Yehuda Kathz of the Ember.js project and Tobias Lutke, Rails Core alumni. It's still in Beta, but works impressively well at this point. They've taken the approach of offering up a full virtualized stack that not only encompasses an IDE but also spins up what they call "boxes" which basically house your entire development stack. This includes your choice of Ruby on Rails, Node.js, Python/Django or Go.

new-box

Similar to C9, they offer basic services that allow you to kick the tires around. This is done by giving you enough "nitrous" points (155) to create a basic box which they say should be enough for most day-to-day tasks. Notice in the image above that the amount of memory and storage selected affects the amount of nitrous points you'll have left. The standard basic box will leave you with five points and like many VPS hosting providers, you can dynamically choose more resources depending on what you need. I'm sure this will come at a cost once it's out of beta but they make it incredibly easy to earn more points without opening up your wallet. Via a couple of different social outreach connections and tasks, you can earn more points towards your box features:

n20-morepoints

Notice that by choosing a couple of options, I was able to boost my N20 points from 155 to 180 and the more friends you invite the more points you earn. Just don't be an annoying spammer though!

Setting up a box though is more than just selecting resources. An important part of this, in terms of performance, is to choose the closest geographic region to you to decrease latency. They actually key in on this during their intro video.

Once you've chosen your settings, provisioning the box is incredibly straightforward and even has a cool animated progress dial:

n20-provision

The IDE then shows up and you're ready to begin your work:

n20-ide

Unlike C9 though, I didn't find a way to visually see the Github repos available. I assumed that connecting to Github would also allow me to easily clone one of my repos into my box. I ended up following these instructions to add the SSH keys generated by Nitrous to my Github account and then git cloning one of my repos into the IDE:

n2o-git-clone

I also could've used the upload functionality to upload my project files:

n20-upload

It just seems to me that getting direct visual access to your GitHub repo is a priority feature the Nitrous team should be looking at and something I think is a plus for C9.

With the files in place, it was time to see how the IDE worked and for all intents seemed to work very well, easily recognizing different file types and offering syntax highlighting according to the file type:

n20-ide-files

Unlike C9, though, there was no autocomplete so you'll need to determine how valuable a feature that is to you. But like C9, keyboard shortcuts for common tasks such as saving a file or closing tabs are all there.

For those used to working in the terminal, you'll find Nitrous easy to adapt to. In fact, you'll really need to be comfortable with it to make full use of the service. Installing and starting packages like MongoDB or Memcached is done via the Nitrous package manager called Parts which, you guessed it, is command-line based. For example, installing MongoDB would go like this:

parts install mongodb

If you're used to apt-get on Linux or brew install on OS X, this syntax should be very familiar.

The main thing to remember is that the editor is only one part of the equation. You're basically running a complete machine here within a web browser so being comfortable in a *nix environment will definitely give you a leg up.

Even deploying your site will require you to use the command-line. There's no "just push a button" option here. Nitrous integrates easily with the following services:

  • Heroku
  • Google App Engine
  • Microsoft Azure
  • Nodejitsu

That gives pretty good coverage to several large cloud-based services. I was curious about their deployment support for Amazon but couldn't find a lot of information on that, at least not enough to be able to understand how to set it up.

With that said, their documentation is very well organized and will easily guide you through most of the tasks you need to get up and running with their service.


To Cloud or Not to Cloud

Both services seem to offer compelling features that could make it easy to move over to full-time cloud-based development. With so many low-cost devices coming out that are clearly targeted at consumers who just want to be connected all the time, it makes sense that these service start to evolve and perhaps gain traction.

It's hard to imagine giving up my trusty laptop with it's i7 processor and speedy SSD for an all-cloud dev environment but I can't outright dismiss it either. Every major software company is touting cloud services and I'm sure every one of you reading this uses multiple cloud services daily. Seems like a logical step to begin considering coding in the cloud.

November 08 2013

17:05

Deeper In the Brackets Editor

Brackets Turns 30 (Ditches the Minivan and Goes for the Jet Pack!)

Nearly one year ago, Jeffrey Way reviewed the open source Brackets project. In the time since that review Brackets has come quite far, recently celebrating it’s 33rd Sprint release. In this article I’ll talk about many of the updates as well as demonstrate why Brackets is my favorite editor.


Ok, What Is Brackets Again?

Brackets primary focus is on web development.

Just in case you aren’t aware, Brackets is an open-source code editor focused on web development and built with web standards. Yes – an editor built with HTML, JavaScript, and CSS. It was originally released in July 2012 on GitHub (http://github.com/adobe/brackets). While launched by Adobe, the commiters behind Brackets include folks from numerous sources. (As an aside, the Brackets team makes it a priority to focus on non-Adobe pull requests.)

Brackets primary focus is on web development. You get the expected editing and code hinting for HTML, CSS, and JavaScript of course, but you also get some powerful features on top of this. The "Live Preview" feature connects your Brackets editor to your browser. As you edit CSS, updates happen in real time providing instant feedback. Just selecting CSS items will provide highlights within the browser so you know exactly what you are working with. Another feature, quick editing, let’s you select an HTML tag and instantly get to the CSS code that applies to that part of the DOM. What isn’t directly supported in Brackets can be achieved via a rich extension API (again using web standards) to let developers add whatever feature they want. Extensions have been created for CSS linting, HTML validation, GitHub integration, and more. (I’m writing this article in Markdown within my Brackets editor using a Markdown extension that gives me a live update of the display.)

That’s where Brackets began. Now let’s talk about where it has come and what we can expect in the future.


The Basics – Covered

Improvements have been made in all aspects (HTML, CSS, and JavaScript).

When Brackets first launched, it was something of an experiment. Could you use web standards to build an editor for web developers? Even more importantly, could you build something that would perform? Because this was something of an experiment and there were many low level architectural concerns, some things that you would expect in any decent editor, like renaming files for example, did not ship for a long time. Brackets was not marketed as being ready for prime time. Instead, the idea was to try something new and see what worked.

It is now fair to say that Brackets has all of the basics covered. Things like creating new files, deleting, opening from the file system, etc. are now baked in. While not necessarily something to crow about, if the lack of these basic features were the only thing keeping you from using Brackets, now is definitely the time to check it out. (And for those of you waiting for a Linux version – one is ready for you!)

Along with basic file operations, code hinting has been dramatically improved over time. Improvements have been made in all aspects (HTML, CSS, and JavaScript). Recently, Brackets added support for parsing and hinting of your own functions. Imagine that you’ve written two JavaScript functions. As you type your calls to these functions, Brackets tries to understand both the arguments and the types of arguments required and provide code support as you type. Here is a simple example:

/*
* @param {number} x First number
* @param {number} y Second number
*/
function ringTheBell(x, y) {
    'use strict';
    var total = x + y;
    return total;
}

function sayHello(name) {
    'use strict';
    return "Hello, " + name;
}

My code has two functions, one called ringTheBell and one called sayHello. I provided some additional metadata for ringTheBell, but that isn’t required. Providing it though will make code hinting a bit nicer. Now I’m going to type a call to ringTheBell:

ch1

Notice how it detected the arguments and and type. If I enter a value for the first argument, notice how the code hinting bolds the second argument:

ch2

Even in cases where Bracket’s can’t determine the type of argument being used in a function, it will still provide you with the name of the argument which can be useful:

ch3

Live Connect for HTML

Recently Brackets added real support for HTML live connect.

Live Connect is probably one of the cooler aspects of Brackets. As I mentioned above, it lets you edit CSS and see updates in real time. Need to tweak padding or margins? You can use your editor and see the impact immediately. Browsers typically allow for this (Chrome Dev Tools), but don’t normally provide an easy way to get those changes back out into source. Chrome has made strides in this area recently, but as much as I love Chrome, I’d rather write my code in an editor.

While that worked great for CSS, it did not support HTML. Brackets would automatically reload your browser on saving an HTML file, but if you wanted to preview your changes without a save, you were out of luck. Recently Brackets added real support for HTML live connect. As you modify your HTML code the browser will update in real time. You will also see highlights in the DOM for the area you’re modifying. This doesn’t really translate well to screenshots, but imagine the following HTML.

<!doctype html>
<html>
    <head>
        <title>Test</title>
    </head>
    <body>

        <h2>This is a Test</h2>
    
        <p>
        fooioikkkllklkkopkk
        </p>
        
    </body>
</html>

If I click in the h2 above, Chrome will render a highlight of that item:

1

If I modify text inside the h2, Chrome will reflect those changes immediately.


Working With Extensions

Another important update to Brackets involves extension support. Behind the scenes, what extensions can do and how they can do it have been progressively improving with each sprint. While not necessarily that important to an end user, for people writing extensions the improvements had made it much easier to add new features to Brackets. If you can spend less time on boilerplate code and more time on features, that’s an all around win for extending Brackets. Brackets also exposes the ability to use Node.js itself for extensions. This feature gives your extensions the ability to make use of anything Node can – which by itself pretty much opens the entire world to you. This is a rather complex topic but if you want to learn more, read this guide: Brackets Node Process.

That’s behind the scenes, but for the end user, Brackets has come a long way in making it easier to actually use extensions. Brackets now ships with a full-fledged Extension Manager. Available via the File menu or an icon in the right gutter, clicking it will launch the manager:

2

Notice that for each extension have installed, you can see details about the version, links for additional information, and even better, a quick way to remove the extension if it is causing problems. At the bottom of this manager is a button that lets you install extensions from a URL. That’s handy if you know what extension you want (as well as the GitHub URL), but what if you don’t? Simply click on the Available tab:

em_available

You can now browse (and even filter) through a long list of available extensions. Even better, installation is as simple as clicking a button. Note the Bracket’s Extension Manager is even smart enough to recognize when an extension may not be compatible with your version of Brackets:

em_bad

Theseus Integration

Probably the most exciting update to Brackets (at least for me) is the integration of the Theseus. Theseus is an open source project created by folks from both Adobe and MIT. It is focused on providing debugging support for both Chrome and Node.js applications. Imagine being able to debug a Node.js application made up of server-side JavaScript as well as client-side code. Theseus provides just that. While still early in development, Theseus is now integrated into Brackets and can be used within the editor itself.

Theseus currently provides three main features:

  • Code coverage in real-time
  • Retroactive inspection
  • Asynchronous call tree

Let’s look at a few examples of these. Theseus’s code coverage support will show how often a function is called. It sounds simple, but can be powerful. I recently tried Theseus on a simple demo that made use of AJAX to call a server-side program. I noticed that my demo wasn’t working, and the Theseus-integration in Brackets confirmed this. Notice the "0 calls" report by my callback:

theseus1

Turns out my server-side code wasn’t set up right and I didn’t write my JavaScript code to support an error callback for the AJAX call. This was literally the first time I played with Theseus and it immediately helped point out a problem in my code. After modifying my front-end code, I could see the difference right away:

theseus2

To be clear, this is all done in real-time. With Brackets open and Chrome open, I can click around in my application and see the updates in Brackets in sync with my actions in the browser.

On top of just seeing the call count, I can also click on an item and see what was passed to it. This is the retroactive inspection feature I mentioned above. Note that you can click into complex properties and really dig into the data.

theseus_log

Finally, for asynchronous calls that my occur at an undefined time after their initial call, Theseus has no problem handling and correctly organizing these calls under their initiator.

theseus_from_site

Adding New CSS Rules

One of the earliest features in Brackets was inline editing for CSS items. You could put your cursor in any HTML element, hit CMD/CTRL+E, and Brackets would scan your project to find relevant CSS files as well as the appropriate matching rule. This made it incredibly easy to quickly update the style sheets applicable for your content.

This worked well – as long as your content actually had a matching CSS rule. In the latest update to Brackets, the editor will now recognize when an element doesn’t have a matching CSS rule.

addnewcss

You can now directly add a new CSS rule right from the inline editor.

addnewcss2

New Theme

Finally, a new "shell" look is being added to Brackets. Currently available to Windows only (but will be in the OSX build soon), the "Dark" look is the future of the Brackets look and feel.

dark

What Next?

Your primary editor is a very personal decision for a developer.

Your primary editor is a very personal decision for a developer. I found myself using Sublime Text a few months ago and noticed that something wasn’t working right. Turns out, I was trying to use a Brackets feature. That day I switched from Sublime as my primary editor to Brackets. I still use Sublime (and to be clear, it is a pretty darn awesome editor!) but now my day to day work is done almost entirely in Brackets.

Obviously I’d love for you to go – right now – and download Brackets. But if you want to dig a bit more before you commit (hey, I understand, building a relationship with an editor is a serious undertaking), check out these resources:

  • First and foremost, the Bracket’s home page is your core location for everything about Brackets.
  • Even if you have no plans on contributing to Brackets, looking at the source code on GitHub would be a great way to look at a seriously cool application built with web standards.
  • Have a question or a problem with Brackets? Head over to the Google Group to post your question. That’s where I go when I have problems and I typically get help pretty quickly.
  • Finally, if you want to know what’s coming next with Brackets, you can find everything at the Trello board.

November 01 2013

16:18

Using BrowserStack for Cross-Browser Testing

Browser testing is the bane of our existence. Well, that's a bit of an exaggeration, but not by much. Multiple browser versions and browser fragmentation can make it difficult to get good test coverage for your sites especially when you factor in the different operating systems developers use to build with.

Over the years, we've relied on a variety of tools to help us with this challenge including virtual machines, tools that simulate browsers and even having multiple devices on hand to work with. It'd be great if there were a way to have one viewport that allowed us to easily test across any major browser and their individual versions without jumping through hoops.

BrowserStack.com aims to offer this via it's browser-based virtualization service and in this article we'll cover the service and how it helps tackle the cross-browser testing problem.


Browsers Inside Your Browser

I mentioned that BrowserStack offers a virtualization service. What most developers think of when they hear that is "virtual machines" and not in a fond way. Virtual machines, while certainly useful, require valuable disk space and resources to be useful and most developers loathe having to run them because of that. BrowserStack takes a different approach by leveraging Adobe Flash to provide a virtualized browser within your own browser. You're not required to install anything and you're getting access to real virtual browsers in the cloud.

To give you an example, using the service I pulled up the Nettuts+ main page via Safari 5.1 on OSX Lion while using Internet Explorer 11.

bs-nettuts-page

That's pretty powerful functionality and the key thing is that it's all done within your browser. And of course you're not limited in OS choice or browser versions. BrowserStack offers virtulization for:

  • Windows XP, 7 and 8
  • OSX Snow Leopard, Lion and Mountain Lion
  • iOS
  • Android
  • Opera Mobile
bs-oses

That's right, they offer mobile browser virtualization. We're in a mobile world, so I'd expect nothing less.

Depending on the operating system you choose, BrowserStack offers up a number of supported browsers for the specific OS including betas and nightlies in some cases.

bs-browsers

Yes, even the dreaded IE6 is available. It can't die soon enough.

Apart from the OS and browser options, you can also choose the screen resolution you'd like to test with which is especially useful for checking out your responsive layouts. Just know that BrowserStack also has a complementary service to tackle responsive designs which generates screenshots for different devices and sizes.

The main point is that there's extensive test coverage here without the need to install anything to use it.


How Does It Work?

The first thing you need to do is register for the service. BrowserStack is a for-pay service and I think the pricing is very reasonable for the functionality you're getting and yes there's a whole lot more features.

Once you've registered and signed in, you'll be at the dashboard which offers a quick start dialog.

bs-quick-start

This allows you to easily enter the URL you'd like to test and via the dropdowns, the target OS and browser version. You can fine tune things via the left panel which offers screen resolution choices and page rendering speed simulation.

Clicking start kicks off the process of establishing the connection via Flash to the remote server and rendering the virtualized browser:

bs-flash-start

What I'd like to emphasize here is that this is not a screenshot grabber or some fake session. You have full access to the web page's functionality including menus, buttons, and so on. This also includes the developer tools that come with browsers. Yes, you read correctly. You have access to tools like Firefox Web Developer Tools, the IE F12 Tools and the Chrome Developer Tools. In this screenshot, I'm in a session running Firefox on Mountain Lion and using the Firefox Web Developer Tools.

bs-dev-tools

So not only can you see how your pages will render across browsers but you can also use the existing tools to debug common issues. Very cool!


Going Local

It's definitely awesome to be able to check out your pages once they're publicly available but in most cases, you're going to be developing locally and will want to checkout your pages way before pushing your code to production.

BrowserStack has addressed this by providing a tunneling capability that allows you to test your local pages remotely. It uses a Java applet to act as a proxy between your directory or web server and the cloud-based service. Yes, this means you'll need to install Java and while I tend to not recommend installation of the Java browser plugins, in this case it's a necessity and worthwhile. BrowserStack isn't installing a plugin though. It's serving an applet that leverages Java's applet browser plugin. Just be sure to disable the browser plugins after you're done testing. A thing to note is that during my testing on Windows 8.1, I needed to use the 32-bit version of the Java JRE as the 64-bit didn't seem to work nor would it install the browser plugins into Firefox or Chrome. To get the 32-bit version, go to Oracle's manual download page. Also be aware that Firefox will not enable the plugin by default so you'll need to go in and activate it.

Looking at the left panel on the BrowserStack dashboard, you should see a section titled "Local Testing" with two buttons labeled "Web tunnel" and "Command line".

bs-local-1

The "Web Tunnel" option leverages the Java applet to establish the tunnel between your computer and the remote service. This could be done at the file system level where you would select a specific directory with your pages or a local server URL (example: localhost). To illustrate this, I’ve installed WAMP on my PC to have a local webserver to use with BrowserStack. WAMP by default also installs phpMyAdmin which is accessible via:

http://localhost:81/phpmyadmin/

I'm using port 81 as to not conflict with another process I'm running. Clicking the "Web Tunnel" option opens the following dialog letting you know that the applet is loading:

bs-applet-1

Because Oracle has worked to secure Java, especially their browser plugins, you should be prompted to run the applet. My advice is to never allow any unsigned applet from a website to run on your PC so I always set my Java security setting to "High". There's also an option called "Very High" but using that will prevent the BrowserStack applet from connecting remotely.

bs-applet-2

Once the applet is running, you'll be presented with a dialog asking for your local server address or folder.

bs-tunnel

As you can see, I entered my local URL and it detected the port number. You can also use SSL if you need to. From there, I kick off the connection and I'm able to see my local copy of phpMyAdmin on the BrowserStack remote server.

bs-tunnel-2

Now, if you don't want to use the Java applet in the browser or for some reason it doesn't work, you can use the "Command line" option which requires that you download the a .jar file which is called via the command line to establish the connection:

java -jar BrowserStackTunnel.jar <key> localhost,3000,0

The <key> would be a BrowserStack access key that you'd have to enter. Once the connection is established, you then return to the dashboard to begin testing.

Personally, I prefer the applet approach since it's dead simple. You can get a ton more details on BrowserStack's local testing on this page.


A Whole Lot More

I think you'd agree that from a browser testing perspective, this is a very cool service that makes it substantially easier to do cross-browser testing, even locally. And it's certainly a viable alternative to virtual machines for those running short on system resources.

But BrowserStack offers a lot more including automated functional testing, browser screenshot capture and a responsive design testing service that lets you see how your site will look across multiple devices (not just browsers).

It's one of those services that as a professional developer is certainly worth the investment.

October 25 2013

15:36

Setting Up a Mac Dev Machine From Zero to Hero With Dotfiles

Setting up a new machine can often be an exciting prospect. However, as developers, there are a lot of tools we need that don’t come as standard.

In this post, I’d like to go through some of the techniques I use to help set up my machine quickly, efficiently and with added super powers.


Introduction

After reading this article, you should be able to do the following:

  1. Quickly set up a new machine
  2. Enhance SSH’ing into a Linux box
  3. Easily absorb smart configs from other developers on GitHub
  4. Optionally share your setup with other developers and participate
  5. This is how all professional developers maintain their configurations

Before we begin, you’ll need some understanding of Git and using the command line. If you’re not sure what these are, I’d recommend looking over the following first:


Superhero Dotfiles

What if you could style Terminal, make the speed of Mission Control faster, run g instead of git, have tab autocomplete regardless of filename case, check for software updates daily, not just once per week? What if you could automate setting up all these features with a single script? Sound good? Then this post is for you.

In many respects setting up a new machine is very much down to personal taste. I’m always refactoring and re-evaluating and I’d advise you to do the same. Find out what works best for you and share your knowledge.

TL;DR: Invest time learning to configure your machine and automate processes, you’ll get that time back ten fold.

Dotfiles, so called because the filename begins with a . are found in the user’s home directory. These files are created as you install and configure your machine. I think of each dotfile as a superhero each containing its own super powers. I’m going to go over each superhero dotfile and the powers that lie within. But first…

There’s a lot to be said for the awesomeness of dotfiles, setting up configurations automatically and speeding up processes. It may be tempting to clone a repository and run dotfiles straight away, but I’d advise against this as the outcome may have undesired results.

Baby Steps

First of all I’d recommend cloning some existing dotfiles repositories. Doing so will allow you to start to understand the file structure and get an overview of the code. The following are GitHub repos of from some top developers who have shared their dotfiles:

It may seem daunting at first glance, but don’t panic, I’ll be going over each dotfile that I use when I setup a new machine. After reading this post, when you’ve got a better understanding of each file and what they can do I’d recommend creating your own repository and taking advantage of existing dotfiles to build it up. You can then add the files and code in that’s best going to suit your requirements.

As people generally name their dotfiles repo dotfiles I set the folder structure up like so:

└── dotfiles
    ├── mathias
    │   └── dotfiles
    │       ├── LICENSE-MIT.txt
    │       ├── README.md
    │       ├── bin
    │       │   ├── bash -> /usr/local/Cellar/bash/4.2.45/bin/bash
    │       │   ├── httpcompression
    │       │   └── subl -> /Applications/Sublime\ Text\ 3.app/Contents/SharedSupport/bin/subl
    │       ├── bootstrap.sh
    │       └── init
    │           └── Mathias.terminal
    ├── paulirish
    │   └── dotfiles
    │       ├── README.md
    │       ├── bin
    │       │   ├── github-email
    │       │   └── spot
    │       ├── install-deps.sh
    │       └── sync.sh
    └── simonowendesign
        └── dotfiles
            ├── bootstrap.sh
            ├── init
            │   ├── Mathias.terminal
            │   └── SolarizedDark.terminal
            ├── install-deps.sh
            └── readme.md

Here, I’m setting up a main folder called dotfiles, then a folder with the username and then the repo. The reason I recommend setting it up like this is to avoid confusion. Some of the code is fairly similar, so I find it useful to easily see whose code I’m looking at. For example if I had 4 or more repos all named ‘dotfiles’ this process would be much more difficult.

(Want to know how I output the folder structure like that? I used this awesome thing called tree, installed in the .brew file.)

Let’s break each file down and look at what’s going on.


Superhero Dotfiles and Their Super Powers

Dotfiles are split into two main types. Those that contain a set of commands and only run once, .osx for example runs a list of commands and gives OS X super powers. Other files such as .bash_profile and .bashrc run each time you open a new Terminal session and gives your Terminal super powers.

Here’s a run down of the dotfiles in my repo and a description of what they can do.

.brew

It’s best to run this first. Once it checks that Homebrew is up to date, it will be used to install useful tools such as tree.

brew install tree

Instead of having to go to a site and download an app, it’s also possible to automate the installation of some apps using brew-cask, such as:

brew cask install dropbox
brew cask install google-chrome

bootstrap.sh

This file is like turning the key in a car to start the engine.

When ran it will sync the local repo and the one on GitHub, then copy those files to your home folder, overriding any existing files if they exist.

Therefore, before running bootstrap.sh it’s a good idea to backup your existing dotfiles and save them somewhere else. A handy shortcut to get to your dotfiles in the Finder:

Finder > Cmd + Shift + g > ~

I use an app called TotalFinder, this adds some nice features to the Finder. Tabbed windows and a shortcut to show and hide hidden files for example I find very useful.

In bootstrap.sh you’ll notice source ~/.bash_profile. This means that if you run bootstrap.sh and have any Terminal windows open, your new settings will be applied without the need of a restart.

.bash_profile / .bashrc

When you open a new Terminal session, this file is loaded by Bash. It loads in the other dotfiles path,bash_prompt,exports,aliases,functions,extra and configures some useful settings such as auto correcting typos when using cd completion.

In some instances .bashrc can be loaded, so this file makes sure that .bash_profile is called.

I like my Terminal clean and clutter free, so I opt not to display the username / computer name at the top by default with this file.

Clean Terminal

.path

This file speeds up the process of running executable files. Rather than having to cd back and forth across various paths to executable files, you can set the file paths in your .path dotilfe and then run executable files directly.

Generally this file isn’t held in the public repo as it can contain sensitive information.

Here’s an example ~/.path file that adds ~/utils to the $PATH:
export PATH="$HOME/utils:$PATH"

.bash_prompt

Using this file you can customise and set the various colours of your Bash prompt.

.exports

Sets environment variables, such as setting Vim as the default editor using export EDITOR="vim". It also increases the amount of history saved, useful for backtracking over previous commands you’ve used.

.aliases

This file contains useful aliases to help you write less. For example instead of typing ‘cd ..‘ you can set it here to be ‘..‘. Starting to like these files yet? :)

.functions

Similar to aliases, except functions can take arguments.

Before when I mentioned I was looking over different dotfile repos, I did mkdir to create a directory. After that I’d then need to cd into that directory.

One example of a function I find useful is:

# Create a new directory and enter it
function mkd() {
    mkdir -p "$@" && cd "$@"
}

Now you can simply do mkd. Now, not only have you made the directory, you’re in the directory as well.

.extra

This file is used for adding your personal information and isn’t added to your repository in order to make sure someone doesn’t accidentally fork your project and then start committing using your details. Something nice to add in here would be your Git credentials.

.gitconfig

This file is only used by Git, i.e. only when a git command is invoked. So although there’s an .aliases file, those aliases are run directly.

In .aliases I have g set to git and in .gitconfig, s set to status -s.

Now instead of running:

git status -s

I can simply run:

g s

.gitignore

Set files that you’d like Git to ignore on the entire system. Yay, no more .DS_Store being accidentally committed!

.gvimrc

A small file that adds improves readability for gvim.

.hgignore

Simliar to .gitignore for Mercurial.

.hushlogin

In some instances, for example, when you ssh into a machine, you may be presented with a message. E.g.

                                    _
                                   | |
  _ __ ___  _   _    ___ ___   ___ | |  ___  ___ _ ____   _____ _ __
 | '_ ` _ \| | | |  / __/ _ \ / _ \| | / __|/ _ \ '__\ \ / / _ \ '__|
 | | | | | | |_| | | (_| (_) | (_) | | \__ \  __/ |   \ V /  __/ |
 |_| |_| |_|\__, |  \___\___/ \___/|_| |___/\___|_|    \_/ \___|_|
             __/ |
            |___/
 Welcome to my cool server.
 Any malicious and/or unauthorized activity is strictly forbidden.
 All activity may be logged.

This file prevents this from being shown.

.inputrc

Configures the ‘Readline environment’. This controls the way keys work when you’re entering a command into your shell.

An example of how I find this useful is to make tab autocomplete regardless of filename case:

set completion-ignore-case on

.osx

My favourite of all the dotfiles. It is run once manually for the commands to run and take effect. Depending on what you’ve added to this file, you may need to restart your machine.

Some of the awesome things I love:

  • Disable the “Are you sure you want to open this application?” dialog
  • Check for software updates daily, not just once per week
  • Disable Notification Center and remove the menu bar icon
  • Enable access for assistive devices
  • Set a blazingly fast keyboard repeat rate
  • Finder: allow quitting via ⌘ + Q; doing so will also hide desktop icons
  • When performing a search, search the current folder by default
  • Speed up Mission Control animations

.screenrc

If you use screen http://kb.iu.edu/data/acuy.html this removes the startup message.

.vimrc

I’m not that familiar with vim. However some of the things you can do with this file include Enabling line numbers and adding syntax highlighting.

Sounds like a good idea to me :)

.wgetrc

If you use wget http://www.gnu.org/software/wget/ this adds additional settings such as changing the timeout to 60 seconds rather than the default 15 minutes. It also sets the retry to 3, rather than the default 20!


Dotfiles Are Go!

At this point, I’ve gone over all the files and I’m at a stage where I’m happy with everything in my repo. Anything I wasn’t sure about has been commented out.

Now the exciting part! As it stands we have the dotfiles in a repo but we need to put them in the correct place so they can be found and used.

Think of it like this, we have Thor’s Hammer, Batman’s Utility Belt, Captain America’s Shield, Iron Man’s Suit. All of our heroes know how to use these, but without them they’re lost! We need to give our superheros their weapons so they can use them.

To do this (with my existing dotfiles backed up and my repo all up to date), open Terminal, cd to the repo and run

source bootstrap.sh

Next, cd to ~ and run:

source .osx

Quick restart and… Awesome, super powers are now available!!!


Additional Super Powers

Rupa Z

Do you spend lots of time doing things like this?

cd this/is/the/path/that/i/want/so/i/type/it/all/out/to/get/whereiwant

What if instead you could just do this:

z whereiwant

Yes please. Thank you https://github.com/rupa/z.

To add this, in .bash_profile I added:

# init z https://github.com/rupa/z
. ~/z/z.sh

And also in install-deps.sh:

cd
git clone https://github.com/rupa/z.git
chmod +x ~/z/z.sh

Reverting Things

When you run your dotfiles for the first time, you may find you don’t like a piece of code that has been ran.

For example in the .osx file, I wasn’t too keen with what the following code did:

defaults write com.apple.dock showhidden -bool true

This code changed the opacity on hidden apps in the dock.

To simply revert this behavior to its default state I simply ran the command again, this time changing true to false, as so:

defaults write com.apple.dock showhidden -bool false

This set it back to default.

With most commands it’s quite obvious to revert the command by simply changing true to false or vice versa. With others it’s possible to set back to default using defaults delete e.g. defaults delete NSGlobalDomain AppleHighlightColor. In some instances you may also need to restart the machine.

Custom .osx Commands

For the more advanced dotfile master.

As you gain more knowledge and confidence using dotfiles, you may want to include your own code.

On a new machine if you find you’re manually changing settings, these would be best automated.

To add your own .osx commands can get a bit tricky!

But generally this is a good place to start:

https://github.com/mathiasbynens/dotfiles/issues/5#issuecomment-4117712

  • defaults read > a
  • Change the setting
  • defaults read > b
  • diff a b

Doing this creates a file called a and b then displays the difference between them, with this knowledge you can then open up the file b in Sublime Text 2, search for the bit that changed and try and work out the command to change it. If you try out this method, good luck!


Conclusion

So, there you have it! Go forth, have fun with dotfiles, look forward to giving your machine super powers and the next time you need to set up a machine from scratch, you can smile to yourself as the whole process is automated.

Thanks very much for stopping by, please comment below if you have any questions or suggestions.

I’m especially interested to see your own .dotfiles repos and any new additions you make, so feel free to add a link to your dotfiles repo in the comments below.

Special Thanks

This blog post wouldn’t have been possible without the wonderful help from the community, special thanks to @mathias, @paul_irish, @reybango and @AndrewPerkins.

October 14 2013

17:10

Tips to Avoid Brittle UI Tests

In the last article I talked about a few ideas and patterns, like the Page Object pattern, that help write maintainable UI tests. In this article we are going to discuss a few advanced topics that could help you write more robust tests, and troubleshoot them when they fail:

  • We discuss why adding fixed delays in UI tests is a bad idea and how you can get rid of them.
  • Browser automation frameworks target UI elements using selectors and it’s very critical to use good selectors to avoid brittle tests. So I give you some advice on choosing the right selectors and targeting elements directly when possible.
  • UI tests fail more frequently then other types of tests, so how can we debug a broken UI test and figure out what caused the failure? In this section I show you how you can capture a screenshot and the page’s HTML source when a UI test fails so you can investigate it easier.

I am going to use Selenium for the browser automation topics discussed in this article.

Much like the previous article the concepts and solutions discussed in this article are applicable regardless of the language and UI framework you use. Before going any further please read the previous article as I am going to refer to it and its sample code a few times. Don’t worry; I’ll wait here.


Don’t Add Delays to Your Tests

Adding Thread.Sleep (or generally delays) feels like an inevitable hack when it comes to UI testing. You have a test that fails intermittently and after some investigation you trace that back to occasional delays in the response; For example, you navigate to a page and look or assert for something before the page is fully loaded and your browser automation framework throws an exception indicating the element doesn’t exist. A lot of things could contribute to this delay. For example:

  • The web server, the database and/or the network are overloaded and busy with other requests.
  • The page under test is slow because it loads a lot of data and/or queries a lot of tables.
  • You’re waiting for some event to happen on the page which takes time.

Or a mix of these and other issues.

Let’s say that you have a page that normally takes less than a second to load but the tests hitting it fail every now and then because of occasional lag in response. You have a few options:

  • You don’t add a delay: in this case the tests that hit that page are sometimes going to fail which reduces your trust in the tests.
  • You add a one-second delay to the tests hitting that page: in this case all of those tests are always going to take one second longer, even when the page loads fast, but even then the tests are not guaranteed to pass as the page might sometimes take longer then a second to load.
  • You might decide to add a few-second delay: this makes sure the page is definitely always loaded, but now your UI tests are taking longer and longer.

You see, there is no winning with arbitrary delays: you either get a slow or a brittle test suite. Here I am going to show you how to avoid inserting fixed delays in your tests. We are going to discuss two types of delays which should cover pretty much all cases you have to deal with: adding a global delay and waiting for something to happen.

Adding a Global Delay

If all of your pages take around the same time to load, which is longer than expected, then most tests are going to fail due to untimely response. In cases like this you can use Implicit Waits:

An implicit wait is to tell WebDriver to poll the DOM for a certain amount of time when trying to find an element or elements if they are not immediately available. The default setting is 0. Once set, the implicit wait is set for the life of the WebDriver object instance.

This is how you set an implicit wait:

WebDriver driver = new FirefoxDriver();
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(5));

This way you’re telling Selenium to wait up to 5 seconds when it tries to find an element or interact with the page. So now you can write:

driver.Url = "http://somedomain/url_that_delays_loading";
IWebElement myDynamicElement = driver.FindElement(By.Id("someDynamicElement"));

instead of:

driver.Url = "http://somedomain/url_that_delays_loading";
Thread.Sleep(5000);
IWebElement myDynamicElement = driver.FindElement(By.Id("someDynamicElement"));

The benefit of this approach is that FindElement will return as soon as it finds the element and doesn’t wait for the whole 5 seconds when the element is available sooner.

Once implicit wait is set on your WebDriver instance it applies to all actions on the driver; so you can get rid of many Thread.Sleeps in your code.

5 seconds is a wait I made up for this article – you should find the optimal implicit wait for your application and you should make this wait as short as possible. From the API documentations:

Increasing the implicit wait timeout should be used judiciously as it will have an adverse effect on test run time, especially when used with slower location strategies like XPath.

Even if you don’t use XPath, using long implicit waits slows down your tests, particularly when some tests are genuinely failing, because the web driver is going to wait for a long time before it times out and throws an exception.

Waiting for Explicit Events/Changes

Using implicit wait is a great way to get rid of many hardcoded delays in your code; but you are still going to find yourself in a situation where you need to add some fixed delays in your code because you’re waiting for something to happen: a page is slower than all other pages and you have to wait longer, you’re waiting for an AJAX call to finish or for an element to appear on or disappear from the page etc. This is where you need explicit waits.

Explicit Wait

So you have set the implicit wait to 5 seconds and it works for a lot of your tests; but there are still a few pages that sometimes take more than 5 seconds to load and result into failing tests.

As a side note, you should investigate why a page is taking so long first, before trying to fix the broken test by making it wait longer. There might be a performance issue on the page that’s leading to the red test in which case you should fix the page, not the test.

In case of a slow page you can replace fixed delays with Explicit Waits:

An explicit waits is code you define to wait for a certain condition to occur before proceeding further in the code.

You can apply explicit waits using WebDriverWait class. WebDriverWait lives in WebDriver.Support assembly and can be installed using Selenium.Support nuget:

/// <summary>
/// Provides the ability to wait for an arbitrary condition during test execution.
/// </summary>
public class WebDriverWait : DefaultWait<IWebDriver>
{
  /// <summary>
  /// Initializes a new instance of the <see cref="T:OpenQA.Selenium.Support.UI.WebDriverWait"/> class.
  /// </summary>
  /// <param name="driver">The WebDriver instance used to wait.</param><param name="timeout">The timeout value indicating how long to wait for the condition.</param>
  public WebDriverWait(IWebDriver driver, TimeSpan timeout);

  /// <summary>
  /// Initializes a new instance of the <see cref="T:OpenQA.Selenium.Support.UI.WebDriverWait"/> class.
  /// </summary>
  /// <param name="clock">An object implementing the <see cref="T:OpenQA.Selenium.Support.UI.IClock"/> interface used to determine when time has passed.</param><param name="driver">The WebDriver instance used to wait.</param><param name="timeout">The timeout value indicating how long to wait for the condition.</param><param name="sleepInterval">A <see cref="T:System.TimeSpan"/> value indicating how often to check for the condition to be true.</param>
  public WebDriverWait(IClock clock, IWebDriver driver, TimeSpan timeout, TimeSpan sleepInterval);
}

Here is an example of how you can use WebDriverWait in your tests:

driver.Url = "http://somedomain/url_that_takes_a_long_time_to_load";
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
var myDynamicElement = wait.Until(d => d.FindElement(By.Id("someElement")));

We are telling Selenium that we want it to wait for this particular page/element for up to 10 seconds.

You are likely to have a few pages that take longer than your default implicit wait and it’s not a good coding practice to keep repeating this code everywhere. After all Test Code Is Code. You could instead extract this into a method and use it from your tests:

public IWebElement FindElementWithWait(By by, int secondsToWait = 10)
{
    var wait = new WebDriverWait(WebDriver, TimeSpan.FromSeconds(secondsToWait));
    return wait.Until(d => d.FindElement(by));
}

Then you can use this method as:

var slowPage = new SlowPage("http://somedomain/url_that_takes_a_long_time_to_load");
var element = slowPage.FindElementWithWait(By.Id("someElement"));

This is a contrived example to show what the method could potentially look like and how it could be used. Ideally you would move all page interactions to your page objects.

Alternative Explicit Wait Example

Let’s see another example of an explicit wait. Sometimes the page is fully loaded but the element isn’t there yet because it is later loaded as the result of an AJAX request. Maybe it’s not an element you’re waiting for but just want to wait for an AJAX interaction to finish before you can make an assertion, say in the database. Again this is where most developers use Thread.Sleep to make sure that, for example, that AJAX call is done and the record is now in the database before they proceed to the next line of the test. This can be easily rectified using JavaScript execution!

Most browser automation frameworks allow you to run JavaScript on the active session, and Selenium is no exception. In Selenium there is an interface called IJavaScriptExecutor with two methods:

/// <summary>
/// Defines the interface through which the user can execute JavaScript.
/// </summary>
public interface IJavaScriptExecutor
{
    /// <summary>
    /// Executes JavaScript in the context of the currently selected frame or window.
    /// </summary>
    /// <param name="script">The JavaScript code to execute.</param<<param name="args"<The arguments to the script.</param>
    /// <returns>
    /// The value returned by the script.
    /// </returns>
    object ExecuteScript(string script, params object[] args);

    /// <summary>
    /// Executes JavaScript asynchronously in the context of the currently selected frame or window.
    /// </summary>
    /// <param name="script">The JavaScript code to execute.</param<<param name="args"<The arguments to the script.</param>
    /// <returns>
    /// The value returned by the script.
    /// </returns>
    object ExecuteAsyncScript(string script, params object[] args);
}

This interface is implemented by RemoteWebDriver which is the base class for all web driver implementations. So on your web driver instance you can call ExecuteScript to run a JavaScript script. Here is a method you can use to wait for all AJAX calls to finish (assuming you are using jQuery):

// This is assumed to live in a class that has access to the active `WebDriver` instance through `WebDriver` field/property. 
public void WaitForAjax(int secondsToWait = 10)
{
    var wait = new WebDriverWait(WebDriver, TimeSpan.FromSeconds(secondsToWait));
    wait.Until(d => (bool)((IJavaScriptExecutor)d).ExecuteScript("return jQuery.active == 0"));
}

Combine the ExecuteScript with WebDriverWait and you can get rid of Thread.Sleep added for AJAX calls.

jQuery.active returns the number of active AJAX calls initiated by jQuery; so when it is zero there are no AJAX calls in progress. This method obviously only works if all AJAX requests are initiated by jQuery. If you are using other JavaScript libraries for AJAX communications you should consult its API documentations for an equivalent method or keep track of AJAX calls yourself.

ExpectedCondition

With explicit wait you can set a condition and wait until it is met or for the timeout to expire. We saw how we could check for AJAX calls to finish – another example is checking for visibility of an element. Just like the AJAX check, you could write a condition that checks for the visibility of an element; but there is an easier solution for that called ExpectedCondition.

From Selenium documentation:

There are some common conditions that are frequently come across when automating web browsers.

If you are using Java you’re in luck because ExpectedCondition class in Java is quite extensive and has a lot of convenience methods. You can find the documentation here.

.Net developers are not quite as lucky. There is still an ExpectedConditions class in WebDriver.Support assembly (documented here) but it’s very minimal:

public sealed class ExpectedConditions
{
     /// <summary>
     /// An expectation for checking the title of a page.
     /// </summary>
     /// <param name="title">The expected title, which must be an exact match.</param>
     /// <returns>
     /// <see langword="true"/> when the title matches; otherwise, <see langword="false"/>.
     /// </returns>
     public static Func<IWebDriver, bool> TitleIs(string title);

     /// <summary>
     /// An expectation for checking that the title of a page contains a case-sensitive substring.
     /// </summary>
     /// <param name="title">The fragment of title expected.</param>
     /// <returns>
     /// <see langword="true"/> when the title matches; otherwise, <see langword="false"/>.
     /// </returns>
     public static Func<IWebDriver, bool> TitleContains(string title);

     /// <summary>
     /// An expectation for checking that an element is present on the DOM of a
     /// page. This does not necessarily mean that the element is visible.
     /// </summary>
     /// <param name="locator">The locator used to find the element.</param>
     /// <returns>
     /// The <see cref="T:OpenQA.Selenium.IWebElement"/> once it is located.
     /// </returns>
     public static Func<IWebDriver, IWebElement> ElementExists(By locator);

     /// <summary>
     /// An expectation for checking that an element is present on the DOM of a page
     /// and visible. Visibility means that the element is not only displayed but
     /// also has a height and width that is greater than 0.
     /// </summary>
     /// <param name="locator">The locator used to find the element.</param>
     /// <returns>
     /// The <see cref="T:OpenQA.Selenium.IWebElement"/> once it is located and visible.
     /// </returns>
     public static Func<IWebDriver, IWebElement> ElementIsVisible(By locator);
}

You can use this class in combination with WebDriverWait:

var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(3))
var element = wait.Until(ExpectedConditions.ElementExists(By.Id("foo")));

As you can see from the class signature above you can check for the title or parts of it and for existence and visibility of elements using ExpectedCondition. The out of the box support in .Net might be very minimal; but this class is nothing but a wrapper around some simple conditions. You can just as easily implement other common conditions in a class and use it with WebDriverWait from your test scripts.

FluentWait

Another gem only for Java developers is FluentWait. From the documentation page, FluentWait is

An implementation of the Wait interface that may have its timeout and polling interval configured on the fly. Each FluentWait instance defines the maximum amount of time to wait for a condition, as well as the frequency with which to check the condition. Furthermore, the user may configure the wait to ignore specific types of exceptions whilst waiting, such as NoSuchElementExceptions when searching for an element on the page.

In the following example we’re trying to find an element with id foo on the page polling every five seconds for up to 30 seconds:

// Waiting 30 seconds for an element to be present on the page, checking
// for its presence once every five seconds.
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
    .withTimeout(30, SECONDS)
    .pollingEvery(5, SECONDS)
    .ignoring(NoSuchElementException.class);

WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
  public WebElement apply(WebDriver driver) {
    return driver.findElement(By.id("foo"));
  }
});

There are two outstanding things about FluentWait: firstly it allows you to specify the polling interval which could improve your test performance and secondly it allows you to ignore the exceptions you are not interested in.

FluentWait is quite awesome and it would be cool if an equivalent existed in .Net too. That said it’s not that hard to implement it using WebDriverWait.


Choose the Right Selectors

You have your Page Objects in place, have a nice DRY maintainable test code, and are also avoiding fixed delays in your tests; but your tests still fail!

The UI is usually the most frequently changed part of a typical application: sometimes you move elements around on a page to change the design of the page and sometimes page structure changes based on requirements. These changes on the page layout and design could lead to a lot of broken tests if you don’t choose your selectors wisely.

Do not use fuzzy selectors and do not rely on the structure of your page.

Many times I have been asked if it’s ok to add an ID to elements on the page only for testing, and the answer is a resounding yes. To make our code unit testable we make a lot of changes to it like adding interfaces and using Dependency Injection. Test Code Is Code. Do what it takes to support your tests.

Let’s say we have a page with the following list:

<ul id="album-list">
    <li>
        <a href="/Store/Details/6">
            <span>The Best Of Men At Work</span> 
        </a>
    </li>
    <li>
        <a href="/Store/Details/12">
            <span>For Those About To Rock We Salute You</span> 
        </a>
    </li>
    <li>
        <a href="/Store/Details/35">
            <span>Let There Be Rock</span> 
        </a>
    </li>
</ul>

In one of my tests I want to click on the “Let There Be Rock” album. I would be asking for trouble if I used the following selector:

By.XPath("//ul[@ID='album-list']/li[3]/a")

When possible you should add ID to elements and target them directly and without relying on their surrounding elements. So I am going to make a small change to the list:

<ul id="album-list">
    <li>
        <a id="album-6" href="/Store/Details/6">
            <span>The Best Of Men At Work</span> 
        </a>
    </li>
    <li>
        <a id="album-12" href="/Store/Details/12">
            <span>For Those About To Rock We Salute You</span> 
        </a>
    </li>
    <li>
        <a id="album-35" href="/Store/Details/35">
            <span>Let There Be Rock</span> 
        </a>
    </li>
</ul>

I have added id attributes to anchors based on the unique albums’ id so we can target a link directly without having to go through ul and li elements. So now I can replace the brittle selector with By.Id("album-35") which is guaranteed to work as long as that album is on the page, which by the way is a good assertion too. To create that selector I would obviously have to have access to the album id from the test code.

It is not always possible to add unique ids to elements though, like rows in a grid or elements in a list. In cases like this you can use CSS classes and HTML data attributes to attach traceable properties to your elements for easier selection. For example, if you had two lists of albums in your page, one as the result of user search and another one for suggested albums based on user’s previous purchases, you can differentiate them using a CSS class on the ul element, even if that class is not used for styling the list:

<ul class="suggested-albums">
</ul>

If you prefer not to have unused CSS classes you could instead use HTML data attributes and change the lists to:

<ul data-albums="suggested">
</ul>

and:

<ul data-albums="search-result">
</ul>

Debugging UI Tests

One of the main reasons UI tests fail is that an element or text is not found on the page. Sometimes this happens because you land on a wrong page because of navigation errors, or changes to page navigations in your website, or validation errors. Other times it could be because of a missing page or a server error.

Regardless of what causes the error and whether you get this on your CI server log or in your desktop test console, a NoSuchElementException (or the like) is not quite useful for figuring out what went wrong, is it? So when your test fails the only way to troubleshoot the error is to run it again and watch it as it fails. There are a few tricks that could potentially save you from re-running your slow UI tests for troubleshooting. One solution to this is to capture a screenshot whenever a test fails so we can refer back to it later.

There is an interface in Selenium called ITakesScreenshot:

/// <summary>
/// Defines the interface used to take screen shot images of the screen.
/// </summary>
public interface ITakesScreenshot
{
  /// <summary>
  /// Gets a <see cref="T:OpenQA.Selenium.Screenshot"/> object representing the image of the page on the screen.
  /// </summary>
  /// 
  /// <returns>
  /// A <see cref="T:OpenQA.Selenium.Screenshot"/> object containing the image.
  /// </returns>
  Screenshot GetScreenshot();
}

This interface is implemented by web driver classes and can be used like this:

var screenshot = driver.GetScreenshot();
screenshot.SaveAsFile("<destination file's full path>", ImageFormat.Png);

This way when a test fails because you’re on a wrong page you can quickly figure it out by checking the captured screenshot.

Even capturing screenshots is not always enough though. For example, you might see the element you expect on the page but the test still fails saying it doesn’t find it, perhaps due to the wrong selector that leads to unsuccessful element lookup. So instead of (or to complement) the screenshot, you could also capture the page source as html. There is a PageSource property on IWebDriver interface (which is implemented by all web drivers):

/// <summary>
/// Gets the source of the page last loaded by the browser.
/// </summary>
/// <remarks>
/// If the page has been modified after loading (for example, by JavaScript)
/// there is no guarantee that the returned text is that of the modified page.
/// Please consult the documentation of the particular driver being used to
/// determine whether the returned text reflects the current state of the page
/// or the text last sent by the web server. The page source returned is a
/// representation of the underlying DOM: do not expect it to be formatted
/// or escaped in the same way as the response sent from the web server.
/// </remarks>
string PageSource { get; }

Just like we did with ITakesScreenshot you could implement a method that grabs the page source and persists it to a file for later inspection:

File.WriteAllText("<Destination file's full path>", driver.PageSource);

You don’t really want to capture screenshots and page sources of all pages you visit and for the passing tests; otherwise you will have to go through thousands of them when something actually goes wrong. Instead you should only capture them when a test fails or otherwise when you need more information for troubleshooting. To avoid polluting the code with too many try-catch blocks and to avoid code duplications you should put all your element lookups and assertions in one class and wrap them with try-catch and then capture the screenshot and/or page source in the catch block. Here is a bit of code you could use for executing actions against an element:

public void Execute(By by, Action<IWebElement> action)
{
    try
    {
        var element = WebDriver.FindElement(by);
        action(element);
    }
    catch
    {
        var capturer = new Capturer(WebDriver);
        capturer.CaptureScreenshot();
        capturer.CapturePageSource();
        throw;
    }
}

The Capturer class can be implemented as:

public class Capturer
{
    public static string OutputFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "FailedTests");

    private readonly RemoteWebDriver _webDriver;

    public Capturer(RemoteWebDriver webDriver)
    {
        _webDriver = webDriver;
    }

    public void CaptureScreenshot(string fileName = null)
    {
        var camera = (ITakesScreenshot) _webDriver;
        var screenshot = camera.GetScreenshot();

        var screenShotPath = GetOutputFilePath(fileName, "png");
        screenshot.SaveAsFile(screenShotPath, ImageFormat.Png);
    }

    public void CapturePageSource(string fileName = null)
    {
        var filePath = GetOutputFilePath(fileName, "html");
        File.WriteAllText(filePath, _webDriver.PageSource);
    }

    private string GetOutputFilePath(string fileName, string fileExtension)
    {
        if (!Directory.Exists(OutputFolder))
            Directory.CreateDirectory(OutputFolder);

        var windowTitle = _webDriver.Title;
        fileName = fileName ??
                   string.Format("{0}{1}.{2}", windowTitle, DateTime.Now.ToFileTime(), fileExtension).Replace(':', '.');
        var outputPath = Path.Combine(OutputFolder, fileName);
        var pathChars = Path.GetInvalidPathChars();
        var stringBuilder = new StringBuilder(outputPath);

        foreach (var item in pathChars)
            stringBuilder.Replace(item, '.');

        var screenShotPath = stringBuilder.ToString();
        return screenShotPath;
    }
}

This implementation persists the screenshot and HTML source in a folder called FailedTests next to the tests, but you can modify it if you want different behavior.

Although I only showed methods specific to Selenium, similar APIs exist in all automation frameworks I know and can be easily used.


Conclusion

In this article we talked about a few UI testing tips and tricks. We discussed how you can avoid a brittle and slow UI test suite by avoiding fixed delays in your tests. We then discussed how to avoid brittle selectors and tests by choosing selectors wisely and also how to debug your UI tests when they fail.

Most of the code shown in this article can be found in the MvcMusicStore sample repository that we saw in the last article. It’s also worth noting that a lot of code in the MvcMusicStore was borrowed from the Seleno codebase, so if you want to see a lot of cool tricks you might want to check Seleno out. Disclaimer: I am a co-founder of TestStack organization and a contributor on Seleno.

I hope what we’ve discussed in this article helps you in your UI testing endeavors.

September 30 2013

15:13

New Relic & JMeter – Perfect Performance Testing

Following on from the great introductory articles featured recently on Nettuts+, this article looks to show how you can take New Relic to the next level. As a performance monitoring tool New Relic is fantastic, but what about performance testing, before you go live. That’s where JMeter comes in to play. In this tutorial, you will see how we can stress test our application under realistic load, and combine the output of JMeter and New Relic to give you confidence in your applications performance, before releasing into a production environment.

Why wait until deployment to see how your application is going to fare against real world traffic. If there is a bottleneck in your code that degrades the user experience, do you really want that to go live? What if we could find these bottlenecks early, improve performance and deliver a great application to our end users the first time, and maintain that going forward with regular benchmarking. JMeter and New Relic together can give you this perfect performance testing suite.


Demo Application

Before we can begin using New Relic and JMeter we need a simple app to do some performance testing on! So, lets write a simple Ruby Sinatra app that has a service we can test. I won’t go into the creation of this application too much, as you can read up on Sinatra in other articles on Nettuts+.

The application will be faked a little, to allow us to see some interesting results along the lines of what we may see in various applications. We will write a service that takes an id, and depending on that id will return a value either straight away or with a delay. This will show us what can happen if requests are handled quickly or slowly and the impact this has on your apps overall performance as many users make requests.

Here is the code that defines the services:

             require 'sinatra'
             require 'puma'
             require 'newrelic_rpm'

             module Example
             class App < Sinatra::Base
             get '/example/:id' do |id|
             result = id
             if id == '1'
             result = "This is our id: #{id}"
             end
             if id == '2'
             sleep 3
             result = "We waited for id: #{id}"
             end
             result
             end
             end
             end

As you can see this is clearly a contrived example, but the idea is that we have some fast responding services and one with a slight delay. We can now use this app and start to write our performance testing plan in JMeter. Lets first get JMeter installed on our machine.


Hooking Into New Relic

Getting your application reporting to New Relic is a very simple process. New Relic support Ruby, Python, PHP, Java and other platforms, featuring easy to follow guides for all. In the case of Ruby an Sinatra, it is literally a four step process:

  • Add the ‘newrelic_rpm’ gem to your GemFile and ‘bundle install’.
  • In your main ‘app.rb’ where we defined the service route above, add a “require ‘newrelic_rpm’” line.
  • Download the ‘newrelic.ini’ file from your account in New Relic and place in a config folder in your app.
    (Ensuring Monitor Mode is set to ‘true’ for Development if running locally.)
  • Rackup your application and see it listed in New Relic!

Once you have follow these simple steps, you should start to see some data coming through to New Relic as you hit your app with some traffic. You’ll know it’s working when the app is listed and turns green.

newrelic-screen-1

For the sake of completeness, I will just list a brief overview of the main view New Relic provides for your applications. The design on New Relic is mainly to monitor applications that are in production environments with live traffic. The overview screen provides an at a glance look at the current status of your application and how it is responding to customers requests.

The screen can be broken down as follows:

  1. Response Time – this is the average response time of calls across your application.
  2. Apdex – New Relics metric for customer experience. A score more towards 1 indicates the vast majority of user’s
    requests are falling within a reasonable time. The apdex can be useful for alerting when it falls below as set number.
  3. Throughput – the requests per minute (RPM) being made to your application.
  4. Web Transactions – the different routes being accessed in your application. These are ordered by the most time consuming requests.
  5. Error rate – the percentage of requests causing an error. You can click through and debug individual errors here.
newrelic-screen-2

What Is JMeter?

jmeter-logo

JMeter is a Java application that allows you to build up test plans that can stress test your application. You can set everything from the amount of simultaneous users of the service, to the amount of requests they make a second. You can even ramp up the requests to see how your app deals with changing load, just as it could in real world deployment.

As part of this tutorial, I will show the basics of getting a test plan running against your applications, but with a wealth of plugins and documentation there are plenty of tools to handle any kind of performance testing you may need.


Installation and Usage

Installation is fairly straightforward and here we will list instructions for Mac and Linux.

Mac OS X

On a Mac JMeter can be installed very easily via Brew. Once you have Brew try the
following command:

        brew install jmeter

Linux

On a Linux machine, simply download from the JMeter downloads page. Then, simply follow the instructions provided.

All Platforms

Once you have the main JMeter package, we also need to install the standard set of plugins. We will be making use of one plugin in particular later on, therefore we need to add these in to be able to use it. The standard plugin set can be obtained from this link: http://jmeter-plugins.org/downloads/file/JMeterPlugins-1.0.0.zip Once downloaded extract into the JMeter package which is located at: “/usr/local/Cellar/jmeter/” on a Mac, and wherever you installed it to on Linux.


Analysis In New Relic – First We Need a JMeter Test Plan!

So now we have JMeter installed and our simple application, let’s test this app and see how it behaves. When you fire up JMeter you will get this screen:

Now, let’s set the base URL for our requests. Right click on “Test Plan” in the left pane, and choose ‘Add -> Config Element -> HTTP Request Default’. We can now enter our base URL in here like so.

jmeter-screen-2

We can now add the amount of threads or “users” of our system. To do this right click on “Test Plan” again and choose ‘Add -> Threads (Users) -> Thread Group’. We can then enter the users, in this case 20. Make sure to choose the loop count forever option, as this will allow us to control the time and number of requests via a plugin later.

jmeter-screen-3

Once we have the the thread group we can now define the requests we want to make to our application that we are going to performance test. To do this we will add “HTTP Request” to our “Test Plan”. This can found by right clicking on the “Thread Group” and choosing “Add -> Sampler -> HTTP Request”. We can then define the request to make in the pane as below.

jmeter-screen-4

You can see how we dont need to define the base URL, as we did that earlier on and instead just need to add the path for the request. In this case the path is to our ‘example/1′ response. You will also notice I have gone ahead and added the other two requests along with the result and graphing panes, which we will use to analyse the results of the tests. By now you should of got the hang of adding elements and they can be easily found in the menu from their names. The main two of interest are the “Throughput Shaping Timer” and the “Composite Graph”.

The Shaping Timer enables us to map how we want the requests to be made to our application over time. For example, we can configure one request per second for 60 seconds, and then ramp up to five requests a second for 60 seconds and see the effect this has on our response times. Let’s take a look how we configure that in the Shaping Timer pane.

jmeter-screen-5

So, by going in and adding each row, you can define the amount of request to make and for how long it should do this for. We can then view our results using the “Composite Graph”, which shows the transactions made per second against the response time of our requests. This requires minimal configuration, simply adding the two graphs we will combine, then in the settings for the composite graph, add in the graphs we require like so:

jmeter-screen-6

That’s it! We can now run our test plan and start seeing some results. Hit play towards the top of the screen and then click on the composite graph. It will start to ploy out the results as they come in and you can get a picture of how your application is responding. Let’s look at our results.

jmeter-screen-7

We can clearly see the jump in requests at one minute has a fairly sizeable impact on our application. For the first minute the requests are stable at one per second and give response times of around two/three ms. However, when we increase to five, the response times increase slightly hitting five and five m/s. Obviously these are very quick response times in the real world, but we are just showing here how we can increase the load and see the affect, if any, this will have.

Let’s compare these results with the service that has a delay of three seconds. How will that cope with the increase in load? To switch to example two, right click on example one and choose toggle. This will disable that request, then do a toggle on example two and that will enable it. Be sure to click the “Clear All” (Sweeping brush) icon at the top to clear the last run’s results, then hit play.

jmeter-screen-8

Even with the three second delay, the server managed the requests quite well and we see much the same in the way of results for this service. Only a few millisecond increase as the requests increase. With such a simple service, this is to be expected.


New Relic Analytics

The real power now comes with combining this data with New Relic. We could for example, set JMeter to run for half an hour with different variations of load and then use New Relic to analyse the results and use its drill down functionality to look for bottlenecks in the application. These can then be fine tuned, increasing your performance before delivering to your customers.

Again, I won’t go into the setup of New Relic as this is covered in other recent articles on Nettuts+ (See here). But once your application is connected, it’s simply a case of generating the load through JMeter and logging into New Relic to see the results. For this run, I have set up the Shaping Timer to run our load for 30 minutes ramping up the requests from five to 10 and then 15 per second. This should give us some reasonable traffic to look at in New Relic.

jmeter-screen-9

Once the JMeter test has run, we can take a look into New Relic which we can now see has stat on the traffic following through the app.

jmeter-screen-10

This clearly shows the ramping up of the requests, at its peak hitting around 400 request per minute (RPM) and the response times remaining stable at three seconds. We can delve deeper into the stats and look into the transaction we are making. If we click through to the Web Transactions view, we can see the analysis New Relic has done on just this part of the application. If the code that handled the request had more layers to it, such as methods to call other systems to get data before presenting back to the user, we would see more of a breakdown.

For example, on the left it shows we spent 100% of the request time, in that call. If we had multiple stage such as a call to a database, we may see a high percentage there and we would know to optimise the query to the database to increase performance.

jmeter-screen-11

New Relic also provides a great reporting view on your applications data, called Scalability. This report can be really useful to monitor your applications ability to handle increasing load. The graph shows your response time against the requests per minute, and you can clearly see if there is any degradation in the response time as they increase. This is great tool and one you should refer to often both in performance testing like this, but also in your performance monitoring of your production application.

In our example below, it is clear that the application is capable of maintaining a three second response time even as the RPM increases.

jmeter-screen-12

New Relic also provides another view, that of Capacity. This allows us to look at how much of the available resources our application is making use of. It indicates to the developer whether the number of instances serving your application is enough to handle the kind of load you are getting. This is vital to ensure you are not running near capacity and have the ability to handle any spikes in traffic that may occur outside your normal traffic flow. New Relic summarise the page well, next to the analysis of our application here, which we can see is fairing well even on this single instance.

jmeter-screen-13

Conclusion

The aim of this tutorial was to show you how to quickly setup JMeter testing plans for your application, so you can test drive the performance of your application before delivering to your customers. This approach can be used in new projects, ensuring the application you are going to deliver is ready for real world traffic. It can also be used on legacy applications, giving you a baseline performance indicator so that as you make changes going forward you can see whether your application’s performance is improving or decreasing.

By leveraging the great tools provided by New Relic, you can both monitor your application online in real time, but also take its toolset and apply it to your own offline analysis. This will give you, the developer, confidence in your product both as it is being developed and when it is released to the wild.

September 18 2013

17:54

Travis-CI: What, Why, How

Travis CI makes working in a team for a software project easier with automated builds. These builds are triggered automatically when each developer checks in their code to the repository. In this article, we will go through how we can integrate Travis CI easily with our project, which is hosted on Github. With automation, notification and testing in place, we can focus on our coding and creating, while Travis CI does the hard work of continuous integration!


Hello Travis & CI!

Travis CI is a hosted continuous integration platform that is free for all open source projects hosted on Github. With just a file called .travis.yml containing some information about our project, we can trigger automated builds with every change to our code base in the master branch, other branches or even a pull request.

Before we get started with how we can integrate Travis with our project, the following prerequisites will be helpful:

  1. Git
  2. Github
  3. Basic NodeJS
  4. NPM
  5. GruntJS

At the heart of using Travis, is the concept of continuous integration (CI). Let’s say we are working on one feature and after we are done coding, we will typically build the project so as to create the executable as well as other files necessary to run the application. After the build is completed, good practices include running all the tests to ensure they are all passing and everything is working as expected.

The last step is ensuring that whatever we coded is indeed working even after we integrate it into the mainline code. At this point we build and test again. If the integrated build succeeds we can consider that the feature has been fully implemented. Travis CI automates this exact step of triggering a build and test upon each integration to the master branch, other branches or even a pull request, accelerating the time to detection of a potential integration bug.

In the following sections, we will take a simple project and trigger a failing build, correct it and then pass it. We will also see how Travis CI easily works with Github pull requests.


Travis Interface

When we land on the main homepage, we can also see the “busyness” of many open source projects going through automated build. Let’s deconstruct the interface and understand the various parts:

travis-interface
  1. Sidebar: This shows the list of public open source projects on Github currently going through automated builds. Each item has the hyperlinked project name, duration of the build so far and the sequential number of build.
  2. Build in progress [yellow]: A little yellow colored circle beside the project name indicates that the build is in progress.
  3. Build failed [red]: A little red colored circle beside the project name indicates that the build is complete and it has failed.
  4. Build passed [green]: A little green colored circle beside the project name indicates that the build is complete and it has passed.
  5. Project name and links: The title is in the format username/repository and it is linked to the Travis CI build page. The little Octocat symbol beside it links to the Github page of the repository containing its source code.
  6. Types of build: The automated builds can be triggered by committing the code to the master branch, other branches or even a pull request. By visiting the individual tab, we can get more information about the builds.
  7. Build activity: This section will include information about each of the tasks that the build is running.

Step 1: Hello World!

Before we integrate Travis CI, we will create a simple “hello world” project and create some build tasks. Travis supports various programming languages including Python, Ruby, PHP and JavaScript with NodeJS. For the purpose of our demo, we will use NodeJS. Let’s create a very simple file hello.js as defined on the main website of NodeJS:

var http = require('http');

http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n') // missing semi-colon will fail the build
}).listen(1337, '127.0.0.1');

console.log('Server running at http://127.0.0.1:1337/');

Do notice that there is a missing semi-colon so that later on JSHint, a JavaScript linter will be able to detect this and raise an error. We will build the project using a task runner called GruntJS that will include JSHint. This is of course an illustration, but in real projects, we can go on to include various testing, publishing, linting and hinting tasks.

To indicate the various packages required for GruntJS, JSHint and others, we will create a second file called package.json. This file will firstly contain the name and the version number of our simple application. Next, we will define the dependencies needed with devDependencies which will include GruntJS related packages including JSHint. With scripts, we will tell Travis CI to start running the test suite and the command grunt --verbose. Let’s see the full contents of the file: package.json:

{
  "name": "node-travis",
  "version": "0.1.0",
  "devDependencies": {
    "grunt": "0.4.1",
    "grunt-cli": "0.1.9",
    "grunt-contrib-jshint": "0.6.0"
  },
  "scripts": {
    "test": "grunt --verbose"
  }
}

Next, let’s prepare the Gruntfile.js that will include all the tasks required to run our build. For simplicity, we can include just one task – JavaScript linting with JSHint.

module.exports = function(grunt) {

  grunt.initConfig({
    jshint: {
      all: ['Gruntfile.js', 'hello.js']
    }
  });

  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.registerTask('default', 'jshint');

};

Finally, we will run the build that contains only one task after we download all the related packages with npm install:

$ npm install
$ grunt

As expected, the build will not pass because the JSHint will detect a missing semi-colon. But if we place the semi-colon back into the hello.js file and run the grunt command once again, we will see that the build will pass.

travis-fail-pass

Now that we have created a simple project locally, we will push this project to our Github account and integrate Travis CI to trigger the build automatically.


Step 2: Hello World With Travis CI

The very first step in integrating Travis CI is to create a file called .travis.yml which will contain the essential information about the environment and configurations for the build to run. For simplicity, we will just include the programming environment and the version. In our simple project, it is NodeJS version 0.10. The final contents of the file .travis.yml will be as follows:

language: node_js
node_js:
  - "0.10"

Now our project will consist of the following files along with README.md and .gitignore as required:

$ tree
.
|-- .travis.yml
|-- Gruntfile.js
|-- hello.js
|-- .gitignore
|-- README.md
`-- package.json

Let’s now create a git repository and push to a new remote repository hosted on Github:

git init
git commit -m "first commit"
git remote add origin git@github.com:[username]/[repository].git
git push -u origin master
travis-github

Next, log in to Travis CI and authorize Travis CI to access your Github account. Afterwards, visit your profile page to turn on the hook for the Github repository to trigger automated builds with Travis CI.

travis-profile

As a final step to trigger our very first build, we will need to push to Github. Let’s remove the semi-colon in the file hello.js to make a failing build and then push to Github. This will trigger the automated build in Travis CI. Let’s visit the URL: https://travis-ci.org/[username]/[repo] to see the first build in progress!

git add hello.js
git commit -m "removed semi-colon"
git push
travis-build-fail

This failing build in the above example is really a simple illustration. But this situation is reflective of something that might happen in our real projects – we try to integrate our code and the automated build fails. By default, after each build is completed, Travis CI will send emails to the commit author and repository owner. In this way, the developer that pushed the code is immediately alerted and can then fix the integration errors. In our case, let’s just insert the missing semi-colon and push to Github one more time.

git add hello.js
git commit -m "added semi-colon to pass the build"
git push
travis-build-pass

Hurray! The automated build has passed this time. Our code is integrated passing all the required tests. Now each time we try to integrate our changes whether it is to the master branch or even other branches, Travis CI will trigger an automated build.


Pull Requests

Once we have integrated Travis CI into our project, a pull request will also trigger an automated build. This is immensely useful for the repository owner or the developer who is in charge of merging the code base. Let’s see how Travis CI will advise whether the pull request is good to merge or not.

First, using another Github account, let’s fork the original repository and pull request with the following steps:

  1. Fork the original repository
  2. Create a new branch in the forked repository
  3. Make the new changes and commit it
  4. Ensure the feature branch is chosen
  5. Compare and pull request

Merge With Caution

To simulate a failing build in the pull request, we will once again remove the semi-colon in the file hello.js, commit and push the changes and finally pull request.

travis-pull

Upon each pull request, Travis CI will automatically trigger the build. This time, we can also visit the “Pull Requests” tab to see the history of current or past builds triggered due to a pull request.

travis-pull-fail

After Travis CI completes the build, if we visit the pull request page from the original repository, we will see that Travis CI has appended some user-interface changes to alert us that the build has failed.

travis-pull-fail-advise

Good to Merge

This failing build status will be immediately notified to the repository owner as well as the developer who did the pull request. And now, depending on the reason for the failing build, it can be rectified with another commit in the same branch. Hence, let’s add on the semi-colon and pull request one last time. Github will automatically update the pull request page as well.

travis-pull-pass

And finally, when we come back to the original repository’s pull request page, this time we will see a “green” signal to go ahead and do a merge as our build is passing!

travis-pull-pass-advise

Build Configurations

The file .travis.yml defines the build configurations. Our example included just the language type and version, but we can add-on more useful ones as follows:

  1. Language specific. This is an example for Ruby
    	language: ruby
    	rvm:
    	  - 1.9.3
    	
  2. Commands or scripts to run before or after each build. This is an example of a command before running a script:
    	before_script:
    	    - git config --global user.name [myname]
    	
  3. Notifications in terms of emails or chat alerts are sent as declared by the build configurations. This is an example of turning off emails and sending it to IRC:
    	notifications:
    	  email: false
    	  irc: "chat.freenode.net#travis"
    	

Validating .travis.yml

As you can see, the file .travis.yml becomes very important in triggering automated builds. If this file in not valid, Travis CI will not trigger the build upon each push to Github. Hence, ensuring that we have a valid file that Travis CI will interpret correctly is important. For this, we will install a gem called travis-lint and run the file .travis.yml

$ gem install travis-lint
$ travis-lint .travis.yml
travis-lint

Build Status Images

It’s really helpful to include a little image to indicate the current status of the build. The image itself can be accessed from the URL pattern http://travis-ci.org/[username]/[repository-name].png. Another way to quickly access the images embedded in various formats is on the Travis CI project page itself. For example, we can copy the Markdown format and embed in the project’s README.md file.

travis-build

Another cool way to track the build statuses of various open source projects while surfing around Github is to install one of the browser extensions. This will put the build status images prominently right next to each of the project names.


Resources on Travis CI

Here are some resources on the concept of continuous integration as well as learning and integrating Travis CI into our Github projects:

A fantastic way to learn what and how to include the various build configurations in the .travis.yml file is to actually browse through many of the popular open source repositories that already integrate Travis CI. Here are a few:

  1. Ruby on Rails (Ruby)
  2. BackboneJS (JavaScript)
  3. Composer (PHP)
  4. Flask (Python)

I hope this gave you a brief introduction to how we can easily integrate Travis CI in our Github projects. It’s really easy to use, so give it a try and make continuous integration a breeze for your team!

August 28 2013

23:20

Xdebug – Professional PHP Debugging

Our Agenda

  1. Introduction to the topic.
  2. Downloading and installing Xdebug on your local machine (Mac OS X 10.6.6+, MAMP 2.1.1).
  3. Integrating with PhpStorm.
  4. Practice debugging.


What You Will Need

  • A Mac running Mac OS X 10.6.6+.
    • If you are on 10.8.X you may need to install XQuartz as Apple removed X11.
    • If you are on Windows, the whole process is somewhat easier, just hit Google for more details.
  • Apple Xcode 4.6 (free on the Mac App Store).
    • Command Line Tools.
  • Homebrew.
  • A terminal app of your choice.
  • PhpStorm 5+ (many other IDE’s will work as well).

What Is Xdebug?

Well, technically, Xdebug is an extension for PHP to make your life easier while debugging your code. Right now, you may be used to debugging your code with various other simple solutions. These include using echo statements at different states within your program to find out if your application passes a condition or to get the value of a certain variable. Furthermore, you might often use functions like var_dump, print_r or others to inspect objects and arrays.

What I often come across are little helper functions, like this one for instance:

function dump($value) {
    echo ‘<pre>';
    var_dump($value);
    echo ‘</pre>';
}

The truth is, I used to do this too, for a very long time actually.

The truth is, I used to do this too, for a very long time actually. So what’s wrong with it? Technically, there is nothing wrong with it. It works and does what it should do.

But just imagine for a moment, as your applications evolve, you might get into the habit of sprinkling your code all over with little echos, var_dumps and custom debuggers. Now granted, this isn’t obstructive during your testing workflow, but what if you forget to clean out some of that debug code before it goes to production? This can cause some pretty scary issues, as those tiny debuggers may even find their way into version control and stay there for a long time.

The next question is: how do you debug in production? Again, imagine you’re surfing one of your favorite web-services and suddenly you get a big array dump of debug information presented to you on screen. Now of course it may disappear after the next browser refresh, but it’s not a very good experience for the user of the website.

Now lastly, have you ever wished to be able to step through your code, line by line, watch expressions, and even step into a function call to see why it’s producing the wrong return value?

Well, you should definitely dig into the world of professional debugging with Xdebug, as it can solve all of the problems above.


Configuring MAMP

I don’t want to go too deep into the downloading and installation process of MAMP on a Mac. Instead, I’ll just share with you that I’m using PHP 5.4.4 and the standard Apache Port (80) throughout this read.


Your First Decision

A quick note before we start with building our own Xdebug via Homebrew: If you want to take the easiest route, MAMP already comes with Xdebug 2.2.0. To enable it, open:

/Applications/MAMP/bin/php/php5.4.4/conf/php.ini

with a text editor of your choice, go to the very bottom and uncomment the very last line by removing the ;.

The last two lines of the file should read like this:

[xdebug]
zend_extension="/Applications/MAMP/bin/php/php5.4.4/lib/php/extensions/ no-debug-non-zts-20100525/xdebug.so"

Now if you’re asking yourself:

“Why would I want to choose a harder way than this one?”

And my answer to that is, it is never a mistake to look beyond your rim and learn something new. Especially as a developer these days, throwing an eye on server related stuff will always come in handy at some point in time. Promised.


Install Xcode and Command Line Tools

You can get Apple Xcode for free off of the Mac App Store. Once you’ve downloaded it, please go to the application preferences, hit the “Downloads” tab and install the “Command Line Tools” from the list.


Install Homebrew

Homebrew is a neat little package manager for Mac OS X which gets you all the stuff Apple left out. To install Homebrew, just paste the following command into your terminal.

ruby -e "$(curl -fsSkL raw.github.com/mxcl/homebrew/go)"

On a Mac, Homebrew will be the most convenient way to install Xdebug. On Linux however, compiling it yourself is the best way to go; which is not that easy on a Mac.

Tip: Windows users just need to download the *.dll file from Xdebug.org, put it into the XAMPP folder and add the path to their php.ini file.

As a PHP developer, you should from now on be aware of Jose Gonzalez’s “homebrew-php” Github repo, which holds a lot of useful “brews” for you. If you’ve ever asked yourself how to install PHP 5.4 manually, you are right there.

Now if you get into any trouble while installing Homebrew, check out Jose’s Readme.

To complete our Homebrew excursion, we want to “tap” into Jose’s brewing formulae by executing the following commands within your terminal application:

brew tap homebrew/dupes

This will get us some dependencies we need for Jose’s formulae.

brew tap josegonzalez/homebrew-php

Done! Now we should be ready to install Xdebug the comfy way, on a Mac.


Install Xdebug

Back in your terminal application, please execute:

brew install php54-xdebug

If you are on PHP 5.3, just replace the “4″ with a “3″ ;)

The installation will take some time. After it’s done, you’ll see a little beer icon and some further instructions which you can ignore.

So what just happened? Homebrew downloaded all the files including their dependencies and built them for you. As I’ve already told you, compiling yourself on a Mac can be a hassle. At the end, we got a freshly compiled xdebug.so located at /usr/local/Cellar/php54-xdebug/2.2.1/.

Attention: Please note that Homebrew will install PHP 5.4 to your system during the process. This should not influence anything as it is not enabled on your system.

To finally install Xdebug, we just need to follow a few more steps.

Change directory (cd) to MAMP’s extensions folder:

cd /Applications/MAMP/bin/php/php5.4.4/lib/php/extensions/no-debug-non-zts-20100525

You can re-check the path by looking at the last line of /Applications/MAMP/bin/php/php5.4.4/conf/php.ini, as this is where we are going.

Backup the existing xdebug.so just in case:

mv xdebug.so xdebug.so.bak

Then copy your Homebrew Xdebug build:

cp /usr/local/Cellar/php54-xdebug/2.2.1/xdebug.so /Applications/MAMP/bin/php/php5.4.4/lib/php/extensions/no-debug-non-zts-20100525/

If you want to force a copy (cp) command to overwrite existing files, just do cp -X source target.

Last, but not least, we need to modify the php.ini file to load the Xdebug extension file. Open /Applications/MAMP/bin/php/php5.4.4/conf/php.ini with a text editor of your choice, go to the very bottom and uncomment the last line by removing the semicolon at the front. Don’t close the file just yet.

Now relaunch MAMP, go to http://localhost/MAMP/phpinfo.php. If everything went well, you should find this within the output:

xdebug-in-phpinfo

If it did not work, please make sure that you really copied over the xdebug.so and have the right path in your php.ini file.


Start Debugging

Before we can actually start debugging, we need to enable Xdebug. Therefore, I hope you didn’t close out your php.ini, as we need to add this line to the very end, after the zend_extension option:

xdebug.remote_enable = On

Save and close your php.ini file and restart MAMP. Go to http://localhost/MAMP/phpinfo.php again and search for xdebug.remote on the site. Your values should look exactly like mine:

xdebug-remote-in-phpinfo

If they do not, follow the same procedure you used to add remote_enable = On for the other statements at the end of your php.ini file.

Now, open your IDE of choice. You can use Xdebug with a number of popular software solutions like Eclipse, Netbeans, PhpStorm and also Sublime Text. Like I said before, I am going to use PhpStorm EAP 6 for this demo.

Inside of PhpStorm, open the application preferences and find your way to “PHP \ Debug \ DBGp Proxy” on the left hand side, like in the screenshot below:

phpstorm-debug-settings

Now choose your personal IDE key. This can be any alphanumeric string you want. I prefer to just call it PHPSTORM, but XDEBUG_IDE or myname would be perfectly fine too. It is important to set the “Port” value to 9000 as our standard Xdebug configuration uses this port to connect to the IDE.

Tip: If you need to adjust this, add xdebug.remote_port = portnumber to your php.ini file.

Attention: Other components may change this value inside of PhpStorm, so watch out for it if something fails.

Next, click that red little phone button with a tiny bug next to it on the top toolbar. It should turn green. This makes PhpStorm listen for any incoming Xdebug connections.

phpstorm-bug-phone

Now we need to create something to debug. Create a new PHP file, call it whatever you’d like and paste in the following code:

<?php

// Declare data file name
$dataFile = 'data.json';

// Load our data
$data = loadData($dataFile);

// Could we load the data?
if (!$data) {
    die('Could not load data');
}

if (!isset($data['hitCount'])) {
    $data['hitCount'] = 1;
}
else {
    $data['hitCount'] += 1;
}

$result = saveData($data, $dataFile);

echo ($result) ? 'Success' : 'Error';

function loadData($file)
{
    // Does the file exist?
    if (!file_exists($file)) {
        // Well, just create it now
        // Save an empty array encoded to JSON in it
        file_put_contents($file, json_encode(array()));
    }

    // Get JSON data
    $jsonData = file_get_contents($file);
    $phpData  = json_decode($jsonData);

    return ($phpData) ? $phpData : false;
}

function saveData($array, $file)
{
    $jsonData = json_encode($array);
    $bytes = file_put_contents($file, $jsonData);

    return ($bytes != 0) ? true : false;
}

Now this code is falsy by default, but we will fix it in a moment, in the next section.

Make sure everything is saved and open up your browser to the script we just created. I will use Google Chrome for this demo, but any browser will do.

Now let’s take a moment to understand how the debugging process is initialized. Our current status is: Xdebug enabled as Zend extension, listening on port 9000 for a cookie to appear during a request. This cookie will carry an IDE key which should be the same as the one we set-up inside of our IDE. As Xdebug sees the cookie carrying the request, it will try to connect to a proxy, our IDE.

So how do we get that cookie in place? PHP’s setcookie? No. Although there are multiple ways, even some to get this working without a cookie, we will use a little browser extension as a helper.

Install the “Xdebug helper”" to your Google Chrome browser or search for any extension that will do it for the browser you are using.

Once you’ve installed the extension, right click the little bug appearing in your address bar and go to the options. Configure the value for the IDE key to match the key you chose in your IDE, like so:

xdebug-browser-extension

After configuring it, click the bug and select “Debug” from the list. The bug should turn green:

xdebug-browser-extension-active

Now, go back to PhpStorm or your IDE of choice and set a “breakpoint”. Breakpoints are like markers on a line which tell the debugger to halt the execution of the script at that breakpoint.

In PhpStorm, you can simply add breakpoints by clicking the space next to the line numbers on the left hand side:

phpstorm-breakpoint

Just try to click where the red dot appears on the screenshot. You will then have a breakpoint set at which your script should pause.

Note: You can have multiple breakpoints in as many files as you’d like.

Now we are all set. Go back to your browser, make sure the bug is green and just reload the page to submit the cookie with the next request.

Tip: if you set a cookie, it will be available to the next request.

If everything goes according to plan, this window should pop up inside of PhpStorm to inform you of an incoming debug connection:

phpstorm-incoming-debug-connection

Did the window not popup for you? Let’s do some troubleshooting and repeat what needs to be set in order for this to succeed:

  1. You should find Xdebug info inside of phpinfo()‘s output. If not, get the xdebug.so file in the right place and set up your php.ini file.
  2. Set PhpStorm DBGp settings to your IDE key e.g. “PHPSTORM” and port “9000″.
  3. Make PhpStorm listen for incoming debug connections using the red phone icon which will then turn green.
  4. Set a breakpoint in your code, or select “Run \ Break at first line in PHP scripts” to be independent from any breakpoints. Note that this is not suited for practical use.
  5. Get a browser extension to set the Xdebug cookie.
  6. Make sure the browser extension has the same IDE key in it that you chose inside of your IDE.
  7. Reload the page and PhpStorm should get the connection.

If you get the dialog seen on the previous image, please accept it. This will take you into debug mode, like so:

phpstorm-in-debug-mode

You can see that the debugger stopped the script’s execution at your breakpoint, highlighting the line in blue. PHP is now waiting and controlled by Xdebug, which is being steered by your very own hands from now on.

Our main workspace will be the lower section of the IDE which is already showing some information about the running script (the superglobals).

phpstorm-debugger-vars

And would you look at that? There’s the cookie we just set to start the debugging session. You can now click through the superglobals and inspect their values at this very moment. PHP is waiting, there is no time limit, at least not the default 30 seconds.

On the left side, you’ll see a few buttons. For now, only “Play” and “Stop” are of interest to us. The green play button will resume the script. If there is another breakpoint in the code, the script will continue until it reaches the breakpoint and halt again.

The red stop button aborts the script. Just like PHP’s exit or die would do.

phpstorm-debugger-play-stop

Now the really interesting ones come in the upper section of the debug window:

phpstorm-debugger-controls

Let’s quickly check them out:

  1. Step Over: This means step one line ahead.
  2. Step Into: If the blue line highlights, for example, a function call, this button let’s you step through the insights of the function.
  3. Step Out: If you stepped into a function and want to get out before the end is reached, just step out.
  4. Run to cursor: Let’s say that, for example, your file is 100 lines long and your breakpoint was set at line two in order to inspect something. Now you want to quickly run to the point where you just clicked your cursor to – this button is for you. You can click “Step over” n times too ;)

Now don’t worry, as you use Xdebug you will rapidly adapt to the shortcuts on the keyboard.


Actually Debugging Some Example Code

I already told you that the code you copy/pasted is falsy, so you’ll need to debug it. Start stepping over the code, statement by statement.

Note that the blue line only halts on lines which actually contain a command. Whitespace and comments will be skipped.

Once you reach the function call to loadData, please do not step into it, just step over and halt on the if statement.

phpstorm-debugger-you-cant-go-back

You can see two new variables in the “Variables” panel on the bottom of the screen. Now, why did the $data variable return false? It seems like the script should have done its job. Let’s take a look. Go back to line seven to step into the function call -> bam! We get a message informing us that we can not “step back”. In order to get your debugger to line seven again, you need to stop this session and reload the page in the browser. Do so and step into the function call this time.

Stop on the return statement inside of the loadData function and see what happened:

phpstorm-debugger-in-a-function

The $phpData array is empty. The return statement uses a ternary operator to detect what to return. And it will return false for an empty array.

Fix the line to say:

return $phpData;

As json_decode will either return the data or null on failure. Now stop the debug session, reload your browser, and step over the function call this time.

phpstorm-debugger-still-falsy-data

Now it seems like we still have a problem as we step into the condition. Please fix the condition to use is_null() to detect what’s going on:

if (is_null($data)) {
    die('Could not load data');
}

Now it’s up to you to try and step around a bit. I would suggest to revert the script to the original falsy version, debug it with echo‘s and then compare how that feels in comparison to using Xdebug.


Conclusion

Throughout this article you should have gained a lot of new knowledge. Don’t hesitate to read it again and to help a friend set up Xdebug – nothing better than that!

You may want to try replacing your usual debug behavior by using Xdebug instead. Especially with larger, object-oriented projects, as they become much easier to debug and even catch up on the flow, if you don’t get something right away.

Note that this is just the tip of the iceberg. Xdebug offers much more power which needs to be explored as well.

Please feel free to ask any questions in the comments and let me know what you think.

August 22 2013

22:29

How to Collaborate On GitHub

If you don’t already know, GitHub is an incredibly effective way to collaborate on development projects. Providing a place for anyone with an internet connection to have an avenue where they can share code with the world for free (not to mention the robust supporting tools for source inspection and easy viewing of commit histories). GitHub has been adopted by many large open-source projects as their primary home for collaboration and contribution.

But how do you join in and contribute to a project? Sure, you know how to use Git to track changes to files and push those files to a server. But there are major benefits to getting involved in larger open-source projects, and GitHub is arguably the best place to start. Today, we will discuss a few rules of the road for collaborating on open source projects, and give you the knowledge and intuition you will need to get involved.


Start Small

Don’t be afraid to start small

One of the most important things to understand when getting started with collaboration on open-source projects is to recognize your role. Often, there are plenty of things you as a developer can do that don’t involve being an extremely clever programmer. In fact, fear of being an inadequate programmer is often a reason why people don’t get involved in open source projects to begin with. Don’t be afraid to start small: instead of trying to fix a major bug or rewriting an entire module, try finding things like documentation inadequacies or cross-device testing and patching, or even simple syntax errors and grammar issues (like this one from GitHub user mzgol).

These kinds of tasks are a good way to get your foot in the door as a contributor to the project without trying to take on more than you can handle. Sign up for CodeTriage to get automated GitHub Issues sent to your inbox. If one hits your inbox that you feel confident you can take on, work on it and send a pull request. (We’ll talk about how to do that a bit further down in the post.)


Learn the Ecosystem of the Project

With any collaborative effort, a set of conventions has probably been adopted. This may include a vocabulary set, a way of contributing and formatting commit messages, a certain rhythm of collaborating that the contributors have agreed to, or even syntactic standards that have been established. Before you try to get involved with a project, read all documents related to these things. For instance, GitHub has standardized a CONTRIBUTING.md file (check out the guidelines for getting involved with jQuery for a thorough example). These guides are maintained by the people who also maintain the codebase and the master branch.

Another way of understanding the ecosystem of a project is to simply look at the existing codebase and the git log. Reading through the commit messages and perusing the code style can tell you a lot about a project. Read through the project’s documentation, and adopt the vocabulary used so that your contributions maintain continuity and portray a similar voice.

Once you’re part of the project’s cultural ecosystem, how do you actually contribute code?


The Pull-Request Workflow for Code Contribution

The workflow for contributing code can seem daunting at first.

The workflow for contributing code can seem daunting at first. The most important thing to remember is to follow the patterns and standards outlined by the project you are working on (as we have already discussed). The general workflow that GitHub supports is fairly simple.

  1. Fork the target repo to your own account.
  2. Clone the repo to your local machine.
  3. Check out a new “topic branch” and make changes.
  4. Push your topic branch to your fork.
  5. Use the diff viewer on GitHub to create a pull request via a discussion.
  6. Make any requested changes.
  7. The pull request is then merged (usually into the master branch) and the topic branch is deleted from the upstream (target) repo.

Within this workflow, you may see many variations for any given project. For instance, the naming conventions for topic branches vary. Some projects use conventions like bug_345, where 345 is the ID # of a GitHub issue that has been filed. Some projects prefer shorter commit messages than others. Here is a series of commands that would complete the workflow above.

Step 1: Forking

Fork the repo on GitHub.com

github_header
forking

Step 2: Cloning

Clone the repo using the URL in the right sidebar:

git clone git@github.com:jcutrell/jquery.git
clone_url

Step 3: Adding the Upstream Remote

Change into the cloned directory and then at this point, you can add the upstream remote:

cd jquery
git remote add upstream git@github.com:jquery/jquery.git

This will now allow you to pull in changes from the source locally and merge them, like so:

git fetch upstream
git merge upstream/master

Step 4: Checking Out a Topic Branch

However, before you make your own changes, checkout a topic branch:

git checkout -b enhancement_345

Step 5: Committing

Now, you can make your changes, and create a commit that tracks just those changes.

git commit -am "adding a smileyface to the documentation."

Step 6: Pushing

Next, you’ll push this topic branch to your own fork of the project.

git push origin enhancment_345

Step 7: Creating a Pull Request

Finally, you will create a pull request. First, go to your fork of the repo. You might see a “your recently pushed branches”, and if so, you can choose “Compare and Pull Request”. Otherwise, you can select your branch from the dropdown, and subsequently click “Pull Request” or “Compare” at the top right of the repo section.

compare_pull_request
Creating a pull request via the Compare and Pull Request button.
switch_branches
Creating a pull request via the branch dropdown menu.

Either of these will take you to a page where you can create a pull request and comment on the request. This page also includes a visualization of the changes you made. This makes it easy for the project administrator to see what you have done and make easier decisions about whether it is appropriate to merge your commit. If they have questions, they can ask them in the comments; they may also ask you to clean up your pull request and resubmit, and subsequently close the pull request.

Note that it is incredibly important that you show the administrators of a project full respect; after all, you can always use your forked version of the code, and if they chose not to pull in your changes, it is because they have the position to do so. Remember, according to Github Employee Zach Holman‘s take in “How GitHub Uses GitHub to Build GitHub”, pull requests are conversations. This is how they should be treated; instead of expecting your commit to be accepted, you should expect only that it will open conversation about the code that you wrote.


GitHub Issues + Pull Requests = Project Management Zen

GitHub offers GitHub Issues, which is a robust way of creating documented, interactive, automated conversations about bugs or features for any given project. While Issues can be disabled, they are enabled by default. There are a lot of awesome features that Issues has built-in, but one of the most important features is its integration with pull requests. A user can reference an issue in their commit message by simply including the issue’s numerical ID in the commit message. For instance:

git commit -am "Adding a header; fixes #3"

This commit message would automatically mark issue #3 as closed when its associated pull request is accepted. This kind of automation makes GitHub a wonderful tool for development project management.


Seek Out Secondary Channels of Collaboration

Often, large open-source projects benefit from many different kinds of collaborative work.

Don’t get caught up thinking that the only way you can contribute is through pull requests. Often, large open-source projects benefit from many different kinds of collaborative work. For instance, a project like Ruby on Rails was notorious for its community; this community would answer questions on forums and in IRC chatrooms to help build knowledge about the framework, and also would help drive the future direction of the framework by talking about ideas and uncovering bugs.

These channels of collaboration are usually opened up as support environments as mentioned before, such as forums and chatrooms. There may also be email chains, meetups, or conference calls that help define the project’s direction and create a lively, productive community around the project. Without this kind of community, pull requests are far less effective.


Most of All, It’s About Your Attitude

Remember, open source is driven by people who have the attitude that sharing knowledge and building collaborative intelligence is a worthwhile endeavor. Your involvement in these projects will be most effective if you approach a given project with the inquisitive attitude that asks “how can I help?” rather than a closed attitude that says “I’m going to help however I want.” People in the open source world want to work with people who are genuinely driven to help others.


Conclusion

If you are interested in getting involved in an open source project, great! Remember, if you approach the project with the right attitude and start small, you could see your name on pull requests merged into code that is distributed to people all over the world and used every day. Take the time to learn about the project and the people who are involved with the project. Develop a genuine interest in helping the project become better. The power of GitHub and the open-source world is continuing to grow every day; start collaborating with other developers, and you can be a part of that world!

August 08 2013

22:09

The New IE11 F12 Tools

Disclaimer: I work for Microsoft Corporation.

Back in January, I walked you through the features of Internet Explorer 10's F12 Developer Tools. Microsoft's recent release of Windows 8.1 Preview brings with it, not only an update to Internet Explorer (now at v11) but also a welcome refresh to the F12 Developer Tools. The latter is especially important since developers are dependent on them to troubleshoot site-related issues from within IE. Till now the tools have solved most debugging use-cases but it's clear that as sites become more complex, developers need richer tools to work with. This update aims to bring a fresh look and expanded capabilities for developers with a strong focus on the following:

  • An updated, cleaner user interface.
  • New Responsiveness, Memory, and Emulation tools.
  • New and improved functionality in existing tools.
  • An easier and faster workflow.

Some of the updates are simply convenience features meant to streamline developer workflow (e.g.: element breadcrumbs) while some will have a dramatic impact on improving the performance and rendering of web apps.

In this post, we'll go through some of the newest updates and features of the IE11 F12 Developer Tools and in some cases, I'll show you the clear differences in features from previous releases.


UI Reboot

Since its inception, the F12 tools has kept a fairly consistent UI using dropdown menus and a tab-based metaphor to present the various options available. But some nits that always seemed to get in the way were things like the tools popping out into their own window during a debugging session and the tabs taking precious vertical real estate. With IE11, the F12 tools have been greatly redesigned to make the UI more intuitive leveraging a graphics-based navigation system that is positioned as a scrolling ribbon on the left-side of the debugger pane:

ribbon

The menus that used to line the top of the tools have been removed to provide greater clarity to the debugging interface, as well as to free up real estate to work with. In addition, the design of the debugger itself has been greatly refreshed breaking away from a Windows 7 UI-style to a more modern Windows 8 look-and-feel. You can see the major difference below:

win7ui
win8ui

The new user interface is clearly more consistent with the modern elements introduced in Windows 8.


DOM Explorer

While the original DOM inspector tool provided a decent experience, it lacked some key features. The main pain points for me were the lack of live DOM updating, the display order of CSS styles and the inability to see events attached to DOM elements. Thankfully, these have now been addressed in this update.

Since I focus so much on JavaScript, finding attached events was especially frustrating requiring a lot of console-based debugging code and trial-and-error to nail down the called event/method combo. Looking at the screenshot below, you can see how I can click on a specific element, see the event that's attached to it and the method that will be called when the event is fired. This is a huge timesaver from a debugging perspective.

domevents

And while it may seem obvious, a slight but important change to the way the tools display the CSS applied to an element, has just made things substantially easier. Prior to this update the F12 tools would display inherited styles first forcing you to scroll down the styles pane to get to the actual used style for the element.

f12old-css

The team has updated the display so that the most recent styles are displayed first which in my opinion makes a whole lot more sense, especially from a debugging perspective:

f12new-css

Some other great new features that are definitely nice to have are:

  • The ability to right click on any element on a page and inspect that element.
  • Dragging an element to another location from within the DOM explorer.
  • The element breadcrumb that makes navigating an element's hierarchy substantially easier.
  • Intellisense, for easy access to style rules.

Previously, you had to open the F12 tools, click on the DOM inspector arrow and click on an element. This streamlines things quite a bit and brings that experience on par with other debugging tools.

The breadcrumb provides an intuitive way to sift through the hierarchical structure of a DOM element, allowing you to easily click on any part of the breadcrumb to pull up the individual parent element:

breadcrumb

With the new Intellisense-style functionality, when you edit a style or add a new rule, you're immediately presented with a popup that offers you quick access to CSS rules and values. While some of you may be CSS encyclopedias, I for one appreciate not having to remember all of them. :)

intellisense-css

Lastly, with DnD within the DOM explorer, you can interactively test how your elements will look and react when you shift their position within the page layout. The changes are made live, so you receive immediate feedback as you reposition your element.


Tackling UI Responsiveness

There's a LOT more code being placed on the client-side than ever before. Frameworks like Ember.js and Angular are making it substantially easier for developers to build single-page web apps and developers are leveraging HTML5-based features to build immersive games that require high frame rates and response times. With that, comes a whole new set of considerations surrounding page performance and the new F12 tools offer a new tool to help you profile and measure the responsiveness of your user interface. The UI Responsiveness tool is a profiler that allows you to measure framerates and CPU usage to pinpoint any UI performance issues.

By kicking off the profiler, I can track how my CPU reacts to my page and what the visual throughput (AKA frames-per-second) is as different points in the page load cycle.

ui-response

The Timeline details panel offers me even finer details about how specific events or network requests affected the page performance allowing me to dig deeper into any issues and make adjustments to improve my site's performance.

timeline

By looking at each element of the timeline you can see how specific actions, for example styling, can affect the rendering performance.

timer

You can imagine how invaluable this data is, especially to game developers that want to leverage native browser capabilities for gaming and are used to having robust debugging tools in other plugin-based development tools such as Flash.


The Script Debugger

Of all the changes, the most impactful to me have been those to the script debugger, mainly because they helped prevent the rage I felt when I would use it. It was primarily a UX issue in that at the moment you opted to run the debugger, the whole tools panel would pop off the browser viewport and into its own stand-alone popup window. It was a jarring experience to say the least. This update resolves that and ensures that the debugger stays firmly in place.

Another great enhancement is the use of a tab metaphor for displaying each open file you're debugging. The previous version of the tool forced you to re-open each file you needed to debug. The new version shows a tab for each file you're working with making navigation substantially easier.

debug-tabs

Additionally, options that were generally buried in context menus are now firmly highlighted and easily discoverable. It's amazing how many times developers have been surprised when I showed them the pretty print function for formatting JavaScript even though it had been in there since IE8. The feature is now highlighted via an icon at the top of the debugging pane alongside the wordwrap icon.

Last but not least, forget about console.log(). The new tools now support Tracepoints easily allowing you to monitor specific values the same way you would via console.log().


Memory Analysis

Pegging memory issues has always been a drag especially if it's a slow memory degradation issue. The new F12 tools aims to tackle this with its new memory profiler. The tool allows you to take snapshots of your site or app's memory usage over a period of time allowing you to pinpoint which actions or areas of your app may be the root cause of the issue.

memory

By creating a baseline snapshot of your memory footprint followed by subsequent snapshots, you can compare the data gathered to determine the number of active objects and which types of objects are persisting. This includes HTML elements, DOM nodes and JavaScript objects and you can drill into the comparisons of the snapshots to see the change in memory between them for individual objects.

memory-detail

Emulating Other Devices

You're probably all too familiar with the complex dropdowns called "Browser Mode" and "Document Mode". They were meant to help developers troubleshoot issues related to non-modern versions of Internet Explorer. In reality, they were a bit confusing to use and only offered marginal testing support for non-modern IEs. With this new update, the F12 tools have streamlined this to help developers focus testing on the most standards-compliant version of IE, especially if their site is currently running in some compatibility mode.

By changing the document mode to "Edge", a developer can force their site to render in the most recent standards mode supported by that version of IE and work to make the necessary standards-based changes to have their site render cross-browser. In addition, an informational link is provided directly in the tool which takes developers directly to modern.IE, an online resource which offers a scanner for common compatibility issues, virtual machines for the different versions of Internet Explorer, and best-practices for ensuring site compatibility in modern versions of IE.

A new feature that explicitly targets mobile and tablet devices is Geolocation simulation. This allows you to leverage the Geolocation API even if your device isn't connected.


A Great Update

This is a great update to a suite of tools that have served us well, but were definitely in need of some sprucing up. There was a clear focus on offering tools that helped you troubleshoot performance-related issues, something that's incredibly important especially with trends heading towards single-page, native-style apps.

I've done my best to roll-up the great new features added in, but to truly get caught up on the full-breadth of functionality provided in the IE11 F12 Developer Tools, check out the walkthrough offered by the team.

August 06 2013

00:18

Web Assets – Tips for Better Organization and Performance

Remember back to when we had to spend a lot of time optimizing our project’s assets (images, CSS, etc..)? Well today, users have a much faster Internet connection and it appears that we can afford to use bigger images or bigger flash files with a lot of video and pictures inside. However, with the rise of mobile development, we are again back in that same situation. It is extremely important to create well optimized sites, so that we have faster applications, which download less content and respond immediately.


Images

Serve the Proper Size

Often times we use the same images for different parts of our websites. For example, in an online shop, all the products have an overview picture. Let’s say that we have three pages where we have to show those images – one page for listing the products, another page for the product’s details, and a third page which shows only the picture in its original size.

So, we need three different image sizes and if we use the same file for all three different places, then the browser will download the full size image even for the listing page, where we actually may only need a 200×200 picture. If the original file is around 1MB and we have ten products per page, then the user would download 10MB. That’s not a very good idea. If you can, try to generate different images for the different parts of your site, this will save a lot of KBs for your users. It is a good idea to have in mind the current screen resolution. For example, if somebody opens your site on their iPhone, there is no need to serve the giant header image, which you normally use. By using CSS media queries you are able to send an image with a smaller size:

@media only screen 
and (min-device-width : 320px) 
and (max-device-width : 480px) {
    .header {
        background-image: url(../images/background_400x200.jpg);
    }
}

Compression

Sending an image with just the proper dimensions is not always enough. Some file formats can be compressed a lot without losing their quality. There are many programs which can help you out. For example, Photoshop provides a nice feature called Save for Web and Devices:

saveforweb

There are loads of options in this dialog, but one of the most important ones is Quality. Setting it to something like 80% could decrease the file size considerably.

Of course, you can use code to compress the files, but I personally prefer Photoshop and I’m using it whenever possible. Here is a simple example written in PHP:

function compressImage($source, $destination, $quality) {
    $info = getimagesize($source);
    switch($info['mime']) {
        case "image/jpeg":
            $image = imagecreatefromjpeg($source);
            imagejpeg($image, $destination, $quality);
        break;
        case "image/gif":
            $image = imagecreatefromgif($source);
            imagegif($image, $destination, $quality);
        break;
        case "image/png":
            $image = imagecreatefrompng($source);
            imagepng($image, $destination, $quality);
        break;
    }
}
compressImage('source.png', 'destination.png', 85);

Sprites

One of the things that you can do to increase the performance of your application is to reduce the number of requests to the server. So, every new image means a new request. It’s a good idea to combine your images into one. The resulting image is called a sprite and with changing the background-position CSS style you are able to show the exact portion of the image, which you need. For example, Twitter Bootstrap uses sprites for its internal icons:

twittericons

Then in the CSS, you can do something like this, to show whichever portion of the sprite you’d like:

.icon-edit {
    background-image: url("../img/glyphicons-halflings-white.png");
    background-position: -96px -72px;
}

Caching

The browser’s caching mechanism is your friend. Yes, sometimes during development it could lead to some very funny situations, but it really helps to improve your site’s performance. Every browser caches content like images, JavaScript or CSS. There are several ways to control the caching and I suggest that you check out this great article for a detailed review. In general, you can control the process by setting headers, like so:

$expire = 60 * 60 * 24 * 1;// seconds, minutes, hours, days
header('Cache-Control: maxage='.$expire);
header('Expires: '.gmdate('D, d M Y H:i:s', time() + $expire).' GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');

Prefetching

HTML5 is moving forward every day. There is a nice feature called prefetching which tells the browser that you will need some resource in the near future and it should be downloaded now, in advance. For example:

<link rel="prefetch" href="/images/background.jpg">

Data URI Scheme / Inline Images

A couple of years ago I had to develop a simple web page, which was supposed to be just one HTML file. Of course there were several images, which I had to include. Data URI scheme helped me to solve the problem. The idea is to convert your images into a base64 encoded string and place it in the src attribute of the img tag. For example:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot">

By using this approach, your image is actually in the HTML and you save one HTTP request. Of course, if you have a big image the string will be really long. Here is a simple PHP script which converts images to base64 strings:

$picture = fread($fp,filesize($file));
fclose($fp);
// base64 encode the binary data, then break it
// into chunks according to RFC 2045 semantics
$base64 = base64_encode($picture);
$tag = '<img src="data:image/jpg;base64,'.$base64.'" alt="" />';
$css = 'url(data:image/jpg;base64,'.str_replace("\n", "", $base64).'); ';

You may find this useful in some cases, but keep in mind that it doesn’t work very well in IE.


CSS

I like to think that writing CSS is like writing code. You still have to organize your styles, to define different blocks and the relationship between them. That’s why I think CSS management is really important. Every part of the application should have its own styles and they should be nicely separated. Keeping everything into different files provides good organization, but also comes with its own problems.

We all know that the usage of the @import statement is not a very good idea. That’s because every new @import means a new request to the server. And if you have, for example, 20 different .css files it means that the browser will make 20 requests. And the browser doesn’t render/show the page before downloading all the styles. If some of your .css files are missing or it is very large, you will get a big delay before seeing something on the screen.

Use CSS Preprocessors

CSS preprocessors solve all the problems above. You still divide your styles into different files, but at the end, the preprocessor compiles everything into a single .css file. They actually offer a bunch of cool features like variables, nested blocks, mixins and inheritance. The code still looks like CSS, but it is well formatted/structured. There are few popular preprocessors that are worth checking – Sass, LESS, and Stylus. Here is a simple example written in LESS:

.position(@top: 0, @left: 0) {
    position: absolute;
    top: @top;
    left: @left;
    text-align: left;
    font-size: 24px;
}
.header {
    .position(20px, 30px);
    .tips {
        .position(10px, -20px);
    }
    .logo {
        .position(10px, 20px);  
    }
}

will produce

.header {
    position: absolute;
    top: 20px;
    left: 30px;
    text-align: left;
    font-size: 24px;
}
.header .tips {
    position: absolute;
    top: 10px;
    left: -20px;
    text-align: left;
    font-size: 24px;
}
.header .logo {
    position: absolute;
    top: 10px;
    left: 20px;
    text-align: left;
    font-size: 24px;
}

Or, for example if you have styling for a button and want to produce just the same button but with another color for the text, you could do this:

.button {
    border: solid 1px #000;
    padding: 10px;
    background: #9f0;
    color: #0029FF;
}
.active-button {
    .button();
    color: #FFF;
}

Efficient CSS

Normally, most developers don’t think about efficient CSS. The efficiency of the CSS reflects on the page’s rendering and if your styles are inefficient your application will be rendered slowly by browsers. An interesting fact is that browsers parse the CSS selectors from right to left. Which means that the following code:

body ul li a {
    color: #F000;
    text-decoration: none;
}

… is not efficient at all. That’s because the engine will get all the <a> tags and will have to evaluate each of the parent elements to finally collect the needed style. You should also know that in terms of efficiency, the selectors are kind of ranked in the following order: ID, class, tag, and universal. This means that an element with an id set will be rendered faster than an element with just a tag selector. Of course, there is no sense to add ids on all the elements in the DOM tree, but you should definitely check your code and improve it where possible. For example, if you have something like this:

ul #navigation li {
    background: #ff0232;
}

You should remove the ul part, because you have only one #navigation element on the page. Or in the following selector:

body .content p {
    font-size: 20px;
}

It is clear that the .content element is a child of the body tag. All the elements are actually children of this element.

Here are two helpful links on the this topic: developers.google.com and css-tricks.com

File Size

As we mentioned above, it is good to have as little code as possible, because the browser doesn’t render the page before downloading the CSS. Here are few tips to reduce the file size.

Combine similar styles:

.header {
    font-size: 24px;
}
.content {
    font-size: 24px;
}

… transforms to:

.header, .content {
    font-size: 24px;
}

Use shorthands. Instead of:

.header {
    background-color: #999999;
    background-image: url(../images/header.jpg);
    background-position: top right;
}

Write it in this fashion:

.header {
    background: #999 url(../images/header.jpg) top right;
}

Minify your CSS code. I.e. use a tool which generally removes all the spaces and new lines. For example CSSOptimiser or Minifycss. It’s a common practice to use such instruments on the server side of the application. I.e. something written in the language of the back-end. Normally these components minify your code and serve it to the user.

Put Your CSS Files in the <head> Tag

It is good practice to include your .css files in the head tag, that way the browser will download it first.


JavaScript

Reduce the Number of HTTP Requests

Same as with your CSS - it's good to reduce the number of requests being to sent to the server. In most cases, the loading of the JavaScript files will not stop the rendering of the page, but it will make some portions of the page nonfunctional.

Minify Your Code

There are bunch of libraries that do JavaScript minification. It's something that will reduce the files' size, but keep in mind that in a development environment it is good to keep your code clean. Most of these tools change the name of your variables and converts everything into a one-line string, which makes the debugging process almost impossible.

CommonJS, AMD, RequireJS - Give It a Try

JavaScript natively doesn't have a mechanism for managing modules. So, all those things are invented to solve this problem. They provide an API which you can use to define and use modules. For example, here is an example taken from http://requirejs.org/:

<!DOCTYPE html>
<html>
    <head>
        <title>My Sample Project</title>
        <!-- data-main attribute tells require.js to load
             scripts/main.js after require.js loads. -->
        <script data-main="scripts/main" src="scripts/require.js"></script>
    </head>
    <body>
        <h1>My Sample Project</h1>
    </body>
</html>

Inside of main.js, you can use require() to load any other scripts you need:

require(["helper/util"], function(util) {
    //This function is called when scripts/helper/util.js is loaded.
    //If util.js calls define(), then this function is not fired until
    //util's dependencies have loaded, and the util argument will hold
    //the module value for "helper/util".
});

Use Namespaces

If we're talking about code organization then we can't skip the part about namespaces. Natively, there is no such feature in JavaScript, but you can still achieve the same thing with a little code. For example, if you want to build your own MVC framework, you will probably have the following classes:

var model = function() { ... };
var view = function() { ... };
var controller = function() { ... };

If you leave things as they are in the above code, then they become public and there is a greater chance of producing conflicts with other libraries in your project. So, grouping them in an independent object (namespace) makes the framework protected:

var MyAwesomeFramework = {
    model: function() { ... },
    view: function() { ... },
    controller: function() { ... }
}

Follow Design Patterns

There is no need to re-invent the wheel. JavasScript became really popular and there are a lot of good practices out there. Design patterns are reusable solutions for common problems in programming. Following some of them will help you to build a good application. However, if I try to cover them all here, I'd have to write a book, so here are just a few of them:

Constructor Pattern

Use this pattern to create an instance of a specific object type. Here's an example:

var Class = function(param1, param2) {
    this.var1 = param1;
    this.var2 = param2;
}
Class.prototype = {
    method:function() {
        alert(this.var1 + "/" + this.var2);
    }
};

Or you may try this:

function Class(param1, param2) {
    this.var1 = param1;
    this.var2 = param2;
    this.method = function() {
        alert(param1 + "/" + param2);
    };
};

var instance = new Class("value1", "value2");

Module Pattern

The module pattern gives us the ability to create private and public methods. For example, in the code below, the variable _index and the method privateMethod are private. increment and getIndex are public.

var Module = (function() {
    var _index = 0;
    var privateMethod = function() {
        return _index * 10;
    }
    return {
        increment: function() {
            _index += 1;
        },
        getIndex: function() {
            return _index;
        }
    };      
})();

Observer Pattern

Wherever you see subscription or dispatching of events, you'll likely see this pattern. There are observers which are interested in something related to a specific object. Once the action occurs, the object notifies the observers. The example below shows how we can add an observer to the Users object:

var Users = {
    list: [],
    listeners: {},
    add: function(name) {
        this.list.push({name: name});
        this.dispatch("user-added");
    },
    on: function(eventName, listener) {
        if(!this.listeners[eventName]) this.listeners[eventName] = [];
        this.listeners[eventName].push(listener);
    },
    dispatch: function(eventName) {
        if(this.listeners[eventName]) {
            for(var i=0; i&lt;this.listeners[eventName].length; i++) {
                this.listeners[eventName][i](this);
            }
        }
    },
    numOfAddedUsers: function() {
        return this.list.length;
    }
}

Users.on("user-added", function() {
    alert(Users.numOfAddedUsers());
});

Users.add("Krasimir");
Users.add("Tsonev");

Function Chaining Pattern

This pattern is a nice way to organize the public interface of your module. It saves time and improves readability:

var User = {
    profile: {},
    name: function(value) {
        this.profile.name = value;
        return this;
    },
    job: function(value) {
        this.profile.job = value;
        return this;
    },
    getProfile: function() {
        return this.profile;
    }
};

var profile = User.name("Krasimir Tsonev").job("web developer").getProfile();
console.log(profile);

I strongly recommend checking out this book by Addy Osmani. It's one of the best resources that you could find about design patterns in JavaScript.


Assets-Pack

Now that we're nearing the end of this article, I want to share a few thoughts on CSS and JavaScript code management on the server. It's a very common technique to add merging, minification, and compiling into the logic of the application. Often there is some kind of caching mechanism, but all things are happening during runtime. I.e. you probably have code logic, which handles the request for .js or .css files and serves the proper content. Behind this process is the compilation, minifcation or whatever you are using to pack your assets.

In my latest projects I used a tool called assets-pack. It's really helpful and I'll explain in detail what exactly it does, but the more interesting part is how I used it. This library is meant to be used only in development mode, it's not something that stays in your codebase and it's not something that you should deploy on your production server.

The idea is to use the packer only while you are working on the assets (CSS, JS). It actually watches for changes in specific directories and compiles/packs the code into a single file. By using this approach you don't need to think about the minification or compilation. All you have to do is just send the compiled static file to the user. This increases the performance of your application, because it only serves static files and of course makes things simpler. You don't need to set anything on your server or implement unnecessary logic.

Here is how you can setup and use assets-pack.

Installation

This tool is a Nodejs module, so you should have Node already installed. If you don't, just go to nodejs.org/download and grab the package for your operating system. After that:

npm install -g assetspack

Usage

The module works with JSON configuration. When it is used via the command line, you should place your settings in a .json file.

Via the Command Line

Create an assets.json file and execute the following command in the same directory:

assetspack

If your configuration file uses another name or is in another directory, use:

assetspack --config [path to json file]

In Code

var AssetsPack = require("assetspack");
var config = [
    {
        type: "css",
        watch: ["css/src"],
        output: "tests/packed/styles.css",
        minify: true,
        exclude: ["custom.css"]
    }
];
var pack = new AssetsPack(config, function() {
    console.log("AssetsPack is watching");
});
pack.onPack(function() {
    console.log("AssetsPack did the job"); 
});

Configuration

The configuration should be a valid JSON file/object. It's just an array of objects:

[
    (asset object),
    (asset object),
    (asset object),
    ...
]

Asset Object

The basic structure of the asset object is like so:

{
    type: (file type /string, could be css, js or less for example),
    watch: (directory or directories for watching /string or array of strings/),
    pack: (directory or directories for packing /string or array of strings/. ),
    output: (path to output file /string/),
    minify: /boolean/,
    exclude: (array of file names)
}

The pack property is not mandatory. If you miss it, then its value is equal to watch. minify by default is false.

Here are a few examples:

Packing CSS

{
    type: "css",
    watch: ["tests/data/css", "tests/data/css2"],
    pack: ["tests/data/css", "tests/data/css2"],
    output: "tests/packed/styles.css",
    minify: true,
    exclude: ["header.css"]
}

Packing JavaScript

{
    type: "js",
    watch: "tests/data/js",
    pack: ["tests/data/js"],
    output: "tests/packed/scripts.js",
    minify: true,
    exclude: ["A.js"]
}

Packing .less Files

The packing of .less files is a little bit different. The pack property is mandatory and it is basically your entry point. You should import all the other .less files there. The exclude property is not available here.

{
    type: "less",
    watch: ["tests/data/less"],
    pack: "tests/data/less/index.less",
    output: "tests/packed/styles-less.css",
    minify: true
}

If you find any problems, please check the tests/packing-less.spec.js of the repository in GitHub.

Packing Other File Formats

assets-pack works with any file format. For example, we can combine HTML templates into a single file by doing something like this:

{
    type: "html",
    watch: ["tests/data/tpl"],
    output: "tests/packed/template.html",
    exclude: ["admin.html"]
}

The only one thing that you should know here is that there is no minification.


Conclusion

As front-end web developers, we should try to deliver the best performance possible for our users. The tips above aren't supposed to cover all aspects of asset organization and performance, but they are the ones I have dealt with personally during my daily work. Please feel free to share some of your tips below, in the comments.

August 01 2013

18:45

Intro to Tmux

One of the most widely used tools in the web development process is surely the terminal. While you are working on a project, often you find yourself in the position of using the terminal with several tabs open at once, one for launching a local web server, a second tab for managing the database, another for copying files and so on. This can soon become messy and hard to handle. One solution for this problem which works well for me, is the terminal multiplexer, tmux.


What Is Tmux

tmux is a terminal multiplexer: it enables a number of terminals, each running a separate program to be created, accessed and controlled from a single screen.

The definition above, taken from the tmux website, is clear: from one terminal window we can start and control a number of other terminals and in each of them run a different application or a different instance of an application.

tmux is developed on a client-server model. This brings into the game the concept of sessions. A session is stored on the server which holds the representation of a window. Each window can be linked to multiple sessions and moved between them.

On the other hand, multiple clients can be attached to each session. So, one or more users can connect to a tmux session from different computers and they share the same information on the window. This is extremely useful in teaching or collaborating since the users sharing a tmux session see the same information on their terminal windows.

Connecting to a tmux session is done by starting the application with the following command:

tmux attach <session_name>

When one user wants to end the terminal sharing feature, the following command is used:

tmux detach

How to Install Tmux

tmux runs on Linux and Mac. At the moment of writing this article, I am not aware of a Windows version of the application.

For the majority of Linux distributions, there is a package in their repositories:

On Arch (which I use), installation is simply a matter of running the following command:

sudo pacman -S tmux

After installation, you can start tmux by issuing the command tmux in a terminal window. If you want to have it running automatically for each terminal session, a small bit of configuration is needed:

  • In the Settings menu go to Edit Current Profile and set the Command field to tmux as in the screenshot below:
tmux settings

If you are on Mac, iTerm2 comes with tmux installed, and to start it, you should issue the command: tmux.


Features

After installation, if you start a terminal window, the only new thing you’ll notice is the presence of a status line at the bottom of the screen:

terminal with tmux

Let’s take a look at the most common features. For a list of complete features, see the links at the end of this article.

Creating Panes

Or, in other words, splitting the main window. First of all, I must say that each tmux command is prefixed using the following key combination: <Ctrl-b>. This can be changed, but we will learn how to configure and customize tmux later on.

So, in order to split a window vertically (or in right and left panes) the following command should be used:

<Ctrl-b>%

and to split the window in horizontal panes you can use:

<Ctrl-b>"

And the result should look like following:

splitting windows

Moving From One Pane to Another and Positioning Panes

In order to move the cursor from one pane to the other (activating panes), the arrow keys are used. The command looks like this:

<Ctrl-b>[Up, Down, Right, Left]

If you want to go to the previously active pane, you can use the following command:

<Ctrl-b>;

Also, if you are not satisfied with the position of a pane, you can rotate the panes using the command:

<Ctrl-b><Ctrl-o>

Resizing Panes

Once created, you can change each panes size, in one cell step, using:

<Ctrl-b><Ctrl-Up[Down][Left][Right]>

or in five cells step using:

<Ctrl-b><Meta-Up[Down][Left][Right]>

Closing a Pane

When you want to close the current pane you can use:

<Ctrl-b>x

Create a New Window

Sometimes you may want to create another window, for example, to work on another project. This window might contain a completely different set of panes with different programs in each of them. To do so, issue the following command:

<Ctrl-b>c

Then if you want to switch to the next window you can use:

<Ctrl-b>n 

And you can switch to the previous window by using:

<Ctrl-b>p

Or you might select the window interactively with:

<Ctrl-b>w

Closing a Window

In order to close the currently opened window, you use:

<Ctrl-b>&

Copy Mode

Suppose you have issued a command on the terminal and the output of the command does not fit in one screen, so you’ll need to scroll up in order to see the entire output. If you try pressing the Up key, this won’t scroll you up, as it will only show you your command history. To scroll up the screen, use the following command:

<Ctrl-b>[

And then hit one of the following keys: Up, Down, PgUp or PgDn to scroll up or down.

Also, when in this mode you can copy text from the history and then paste it with:

<Ctrl-b>]

In order to exit this insert mode, just hit esc.

Now there are a lot of other commands bound to various keys. You can list all of the key bindings by issuing:

<Ctrl-b>?

Configuring Tmux

tmux is highly configurable. The configuration file is either /etc/tmux.conf for system wide settings or (recommended) ~/.tmux.conf for user specific settings.

Change the Prefix Key

One of the first things that most users change is the mapping of the prefix key (since <Ctrl-b> doesn’t seem to be so handy). Most users change it to <Ctrl-a>. This can be done like so:

set -g prefix C-a
unbind C-b
bind C-a send-prefix

The -g option in the first command tells tmux that this is a global option, meaning this is set for all windows and sessions.

Change the Key Bindings

Some users may prefer Vi or Emacs like bindings for the key actions. This is done using:

set -g status-keys vi
setw -g mode-keys vi

The setw command, sets the option for the window (affects all the panes in a window).

Status Line

You can perform various configurations of the status line: you can turn it on or off, you can change its background and foreground color, you can change what information is displayed inside it, etc.

To turn the status bar off, issue the following command:

set -g status off

Or you may try something like this:

set -g status-bg blue
set -g status-fg white
setw -g status-left #H:#S at #W:#T

… which changes the status line background to blue, the text color to white and displays to the left of the status bar the hostname of localhost, followed by a colon and the session name followed by the ‘at’ string and the window name, a colon, and lastly the pane title.

You can also display the status line at the bottom or at the top of the window:

set -g status-position [bottom | top]

For further information on configuration and other configuration options you can check the options section of the manual.


Conclusion

I hope you have found this introduction to tmux helpful in improving your terminal workflow. I’ve presented here just a few commands that I use most frequently. If you want to learn more, there are several resources that are available. I highly recommend:

Older posts are this way If this message doesn't go away, click anywhere on the page to continue loading posts.
Could not load more posts
Maybe Soup is currently being updated? I'll try again automatically in a few seconds...
Just a second, loading more posts...
You've reached the end.
(PRO)
No Soup for you

Don't be the product, buy the product!

close
YES, I want to SOUP ●UP for ...