About/Contact

Steve Trefethen

Steve Trefethen is CTO at Wanderful Media.
Contact me

View my LinkedIn profile



Calendar

<<  May 2013  >>
MoTuWeThFrSaSu
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

View posts in large calendar

Disclaimer

The posts on this weblog are provided AS IS with no warranties, and confer no rights. The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.



Google Calendar on a Simile Timeline

January 20 2010 11:02PM

At Falafel Software Google calendar is a core tool used by the company. I’ve been working to leverage the data calendar in a number of interesting ways such as in the DIV below rendered using JavaScript based on calendar data from Falafel training calendar displaying upcoming training events over the next 120 days.

February 2

Telerik Advanced RadGrid Data Editing and Validation
FREE! (Click to register)

February 23

Telerik Advanced RadGrid Paging, Sorting, and Filtering
FREE! (Click to register)

March 1

Telerik Sitefinity Online Training
$399/person

I’ve mentioned the above example before from Google’s playground and I found another example which uses $g(MIT’s Simile) project Timeline control to render calendar data. As you can see from that example it’s not actually working so I thought I’d post an update with some changes I made to get it working. Here is my example. I’ve made changes to get the import of the data working though there remains a number of other improvements that could be made. I’ve yet to determine if this timeline view is really all that useful and haven’t settled on a view that I really like. At any rate, here is the code, again take a look at the source for my example above for a complete working page.

var gEventSource;
 
function loadGDataCallback(json) {
  var entries = json.feed.entry;
  var timelinerEntries = [];
  for (var i = 0; i < entries.length; ++i) {
    var entry = entries[i];
    if(entry["gd$when"] == null) continue;
    var when = entry["gd$when"][0];
    var start = convertFromGDataDate(when.startTime);
    var end = convertFromGDataDate(when.endTime);
    var webContent = null;
    var links = entry.link;
    for (var j = 0; j < links.length; ++j) {
      if (links[j].rel == "alternate") {
        webContent = links[j];
        break;
      }
    }
    var title = entry.title.$t;
    var link = entry.link;
    var icon = entry.link[0].href;

    var description = '<img src="' + link + '">';
    timelinerEntries.push(new Timeline.DefaultEventSource.Event(
      start,
      end, // end - when not set, event displayed with icon (looks better)
      null, // latestStart
      null, // latestEnd
      false, // not isDuration
      entry.title.$t,
      entry.content.$t,
      icon, // image
      entry.link[0].href, // link - destination when clicking on title
      entry.link[0].href,
      undefined, // color
      undefined  // textColor
    ));
  }
  gEventSource.addMany(timelinerEntries);
};
 
function zeroPad(n) {
  if (n < 0) throw new Error('n is negative');
  return (n < 10) ? '0' + n : n;
}
 
function convertToGDataDate(/*Date*/ date) {
  return date.getFullYear() + '-' +
         zeroPad(date.getMonth() + 1) + '-' +
         zeroPad(date.getDate());
}
 
function convertFromGDataDate(/*string<YYYY-MM-DD>*/ date) {
  var match = date.match(/(\d{4})-(\d{2})-(\d{2})/);
  return new Date(parseInt(match[1], 10), parseInt(match[2], 10) - 1, parseInt(match[3], 10));
}
 
function onLoad() {
  gEventSource = new Timeline.DefaultEventSource();
 
  var theme = Timeline.ClassicTheme.create();
  theme.event.bubble.width = 320;
  theme.event.bubble.height = 180;
 
  // centering the timeline three months previous makes it look nicer on load
  var threeDaysFromNow =
      new Date(((new Date).getTime()) + 3 * 24 * 60 * 60 * 1000);
  var bandInfos = [
    Timeline.createBandInfo({
        eventSource:    gEventSource,
        date:           threeDaysFromNow,
        width:          "40%", 
        intervalUnit:   Timeline.DateTime.WEEK, 
        intervalPixels: 300,
        theme:          theme
    }),
    Timeline.createBandInfo({
        eventSource:    gEventSource,
        date:           threeDaysFromNow,
        width:          "60%", 
        intervalUnit:   Timeline.DateTime.MONTH, 
        intervalPixels: 550,
        theme:          theme
    })
/*    ,
    Timeline.createBandInfo({
        showEventText:  false,
        trackHeight:    0.5,
        trackGap:       0.2,
        eventSource:    gEventSource,
        date:           threeDaysFromNow,
        width:          "10%", 
        intervalUnit:   Timeline.DateTime.YEAR, 
        intervalPixels: 200
    })
*/    
  ];
  bandInfos[1].syncWith = 0;
  bandInfos[1].highlight = true;
/*  
  bandInfos[2].syncWith = 0;
  bandInfos[2].highlight = true;
*/  
  tl = Timeline.create(document.getElementById("my-timeline"), bandInfos);
 
  // Atom feed from a Google calendar
  var feedUrl = "http://www.google.com/calendar/feeds/4u13qtkl3bcpao0ofgod94s960@group.calendar.google.com/public/full";
 
  var startDate = new Date((new Date).getDate());
  var endDate = new Date(((new Date).getTime()) + 3 * 30 * 24 * 60 * 60 * 1000);

 
  var getParams = '?start-min=' + convertToGDataDate(startDate) +
                  '&start-max=' + convertToGDataDate(endDate) +
                  '&alt=json-in-script' +
                  '&callback=loadGDataCallback' +
                  '&max-results=5000'; // choose 5000 as an arbitrarily large number
  feedUrl += getParams;
  var scriptTag = document.createElement('script');
  scriptTag.src = feedUrl;
  document.body.appendChild(scriptTag);
}
 
var resizeTimerID = null;
function onResize() {
    if (resizeTimerID == null) {
        resizeTimerID = window.setTimeout(function() {
            resizeTimerID = null;
            tl.layout();
        }, 500);
    }
}
I’m interested in any other ways people are using Google’s calendar data so let me know if you done/seen anything cool!
FacebookDel.icio.usDigg It!

Using Google Playground Examples in VS.NET

October 06 2009 5:43AM

image I’ve been working on ways to leverage Google’s Calendar API to publish Falafel’s training calendar entries to the web. One of the things I stumbled into was the Google Code Playground which is a cool tool for testing out various Google API’s. The Playground includes Firebug lite which is also something I hadn’t run into, I love finding new cool things!

At any rate, this post is about how to get from the Playground to something live. In the screenshot to the right you can see the JavaScript source code in a code editor at the top right hand side of the screen. The missing piece here is that to get the code from the Playground to work on your own site you need to do a few things. First, you have to get an API Key. Once you’ve done that you can then add a <script> tag to include the Google GData API in your page.

    <script src="http://www.google.com/jsapi?key=<your_key>" type="text/javascript"></script>

After, that you need to initialize the GData API and get the code from the Playground to execute. To do that I did two things.

  1. Wrapped the JavaScript code from the Playground page in a function.
  2. Added the following code to my page with a reference to call the JavaScript function
    <script type="text/javascript">
        //<![CDATA[

        google.load("gdata", "1");
        google.setOnLoadCallback(loadItems);
        //]]>
    </script>

”loadItems” above is the name of the function I created in Step 1. Next, I had to add a DIV tag to the page as a target for the new content:

<div id="content">
</div>

At this point, the page (plain HTML) can be debugged from VS.NET and/or uploaded to your domain and function correctly. Anyway, I learned a few things along the way and thought this might be useful.

FacebookDel.icio.usDigg It!

Automated testing of ASP.NET web applications using Selenium

July 31 2007 8:06AM

Lately, I've been focused on Web Application testing frameworks and I've been looking at a number of different options and having varying degrees of success. That is, of course, until I started looking at Selenium after Lino mentioned it to me and I'm very impressed. Selenium is an open source project with multiple tools designed for testing web applications. Selenium includes:

  • Selenium IDE an add-on to Firefox use for recording test scripts
  • Selenium RC (Remote Control) a Java server used for execution of test scripts
  • Selenium Core client side testing support for web applications added directly to your application
All of these are interesting in their own right so be sure to look closely at each piece.

Selenium IDE

Selenium IDE
The Selenium IDE is a non-modal dialog add-on for Firefox that supports Selenium test development. In fact, it's more than fair to call this single dialog an IDE because it fully supports recording, development and debugging of test scripts. Additionally, it can format test scripts in any of the following for use with Selenium RC:
  • HTML
  • Java
  • C#
  • Perl
  • PHP
  • Python
  • Ruby

A Selenium test script consists of a series of Commands which have a Target and optionally a Value. For example, browsing to a web page using Selenium consists of the following:

Command: open
Target: http://localhost/myapp

To click on a link titled "About" on a page the Command might look like this:

Command: clickAndWait
Target: link=About

This will initiate the click and wait until the new page is done loading. There are literally hundreds of commands to choose from covering input (both keyboard and mouse), control manipulation, drag/drop, evaluation, verification, waiting, browser manipulation and just about anything else you'll need.

If you've done any UI testing at all you're familiar with the challenge of manipulating a UI programmatically in a manner independent from of the size, position or location of the control you're trying to manipulate. Selenium solves this problem using XPATH and providing the ability to locate controls based on XPATH expressions alleviating the need to hard code HTML tag structure into a test script. This is particularly crucial for ASP.NET testing since the runtime mangles the ID attributes of rendered tags. For example, the ASP.NET runtime may render ID attributes that look like:

id="ctl00_cphContents_gridMaint_DataGrid"

Finding this control using an XPATH expression can be simplified to something like this:

//table[contains(@id, "gridMaint")]

In the event the nesting of the DataGrid changes the script will continue to function properly as long as table's ID contains the text "gridMaint".

Example of using the Find button on the Selenium IDE

Notice the link is highlighted in the browser

Playing back tests using Selenium TestRunner

The Selenium IDE has a toolbar button that will launch a feature called TestRunner which allows you to playback your tests using controls hosted in an IFRAME inside your browser. Here's what it looks like:

Selenium TestRunner

You can playback your entire test from right within your browser. It's like having the IDE built right into your application.

Selenium RC

Next, is Selenium RC which is a Java server application used execute Selenium tests and drive a browser instance through AJAX communication with the browser. To start Selenium RC simply execute the following from a command prompt:

java -jar selenium-server.jar -interactive

Since I'm focused on .NET I'll discuss the C# approach. Once you've recorded and debugged your test you can capture it as C# and compile it into an NUnit compatible assembly where upon execution it will drive Selenium RC to manipulate the web application through a browser instance running on your desktop. Here is an example of the above recorded test in C#:

using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using NUnit.Framework;
using Selenium;

namespace SeleniumTests
{
    [TestFixture]
    public class NewTest
    {
        private ISelenium selenium;
        private StringBuilder verificationErrors;
        
        [SetUp]
        public void SetupTest()
        {
            selenium = new DefaultSelenium("localhost", 4444, "*firefox",
                              "http://localhost:4444");
            selenium.Start();
            verificationErrors = new StringBuilder();
        }
        
        [TearDown]
        public void TeardownTest()
        {
            try
            {
                selenium.Stop();
            }
            catch (Exception)
            {
                // Ignore errors if unable to close the browser
            }
            Assert.AreEqual("", verificationErrors.ToString());
        }
        
        [Test]
        public void TheNewTest()
        {
            selenium.Open("/selenium-ide/");
            selenium.Click("link=About");
            selenium.WaitForPageToLoad("30000");
        }
    }
}

Generation of NUnit compatible tests is great because it makes it really easy to incorporate Selenium test suites into a continuous integration environment like CruiseControl.NET.

Conclusion

If you're in need of a web application testing framework you owe it to yourself to check out Selenium. I'd go so far as to say if you're doing doing any web related development and you're not already using Selenium you should stop right now and go download it. Here are there RSS feeds.

After playing with Selenium for about an hour I was easily able to:

  • Record tests against a RIA
  • Build a C# NUnit compatible assembly to drive Selenium RC
  • Integrate the tests into an automated build using CruiseControl.NET

Since then I've been able to really dig in and accomplish a lot of work in a very short period of time. The next step is to build up a nice battery of tests and dig into NCover to help figure out where the holes are.

Lastly, I just want to tip my hat to the ThoughtWorks and volunteers and supporters of the Selenium project. Kudos for such a great framework!

FacebookDel.icio.usDigg It!

Diving into web application automated testing

July 26 2007 5:14PM

My new job is completely focused on ASP.NET development and being a big believer in automated testing I've been investigating strategies for RIA's. I've found what I think is going to be a solution using Selenium which I'll blog more about later though I'm curious to know what other frameworks people are using? Basically, I don't want to overlook any potential candidates though at this point I'm very happy with Selenium.

What are you doing for automated testing of AJAX enabled Internet applications?
FacebookDel.icio.usDigg It!

Delphi ASP.NET AJAX demo fixed on CodeCentral

January 19 2007 6:23PM
Doh! I just realized one of the Delphi ASP.NET AJAX demos I posted to CodeCentral is missing the actual download zip file. I just fixed the problem so if you're interested you can get it here: Updated: I just uploaded both of these demos to my website so now you can actually see the Delphi versions live (yet another advantage of hosting my own blog). Here are the links: Update: Fixed the spelling of Delphi in this blog entry (doh!)
FacebookDel.icio.usDigg It!

Tags: , ,

AJAX/RSS examples uploaded to code central

November 01 2006 8:14PM
I'm not sure why I hadn't done this before but I just uploaded the two Delphi for .NET AJAX examples and my recent Windows RSS Platform example to CodeCentral. You can find links for all of these downloads on my author page. The examples include:

Updated Jan 19, 2007: Fix URLs

FacebookDel.icio.usDigg It!

Tags: , , ,

An AJAX example in Delphi with ASP.NET using AJAX.NET Professional

March 13 2006 5:23PM

Back in January, I wrote this post about using the magicAJAX.net framework in Delphi to illustrate AJAX from a Delphi ASP.NET application. This month I've been looking at the AJAX.NET Professional framework written by Michael Schwarz and have converted his examples to Delphi for .NET using the 1.1 .NET framework although AJAX.NET Pro supports both 1.1 and 2.0 versions of .NET.

Once again I'm going to assume you'll be running this example from IIS. To get this example to work in Delphi for .NET you'll need to do the following:

  1. Grab the AJAX.NET Pro net download from here. All you're really going to need is the AjaxPro.dll assembly.
  2. Download the Delphi example source code here
  3. Unzip delphi_ajaxpro.zip into \inetpub\wwwroot (it contains a directory called DelphiAJAXDemo)
  4. Create a virtual directory under IIS and point it at the directory created above
  5. Under \inetpub\wwwroot\DelphiAJAXDemo create a directory called "bin"
  6. Unzip AjaxPro.dll from the download in step 1 into the bin directory created above
  7. Start the IDE and open DelphiAJAXDemo.bdsproj
  8. From the Project Manager right click References and select Add Reference and add AjaxPro.dll
  9. Compile and run the project, you should see a page that looks like this

NOTE: I intentionally converted this example as closely to the C# example as possible. I can't say that in all cases I would have written the same code but I felt the comparison between C# and Delphi was important enough to keep the code as similar as possible.

Tags:

Update:
I found a bug in the Class demo code where some data members were not being initialized. I've corrected the code and fixed the download with these latest changes.
Update #2:
I missed the file quickguide.aspx which is now included in the download.

Update #3: Fix blog tags for this entry

Update #4: This demo is now available online here.

FacebookDel.icio.usDigg It!

Tags: ,