     else
       url = URL.parse(@browser.location.href, true)
       for key, value of expected
-        assertMatch url[key], value, message
+        # Gracefully handle default values, e.g. document.location.hash for
+        # "/foo" is "" not null, not undefined.
+        if key == "port"
+          defaultValue = 80
+        else
+          defaultValue = null
+        assertMatch url[key] || defaultValue, value || defaultValue, message
 
 
   # -- Document contents --
 
   # Assert the named attribute of the selected element(s) has the expected value.
   attribute: (selector, name, expected, message)->
+    if arguments.length == 2
+      expected = null
     elements = @browser.queryAll(selector)
     assert elements.length > 0, "Expected selector '#{selector}' to return one or more elements"
     for element in elements

  # Asserts that the global (window) property name has the expected value.
  global: (name, expected, message)->
    actual = @browser.window[name]
    message ||= "Expected global #{name} to have the value '#{expected}', found '#{actual}'"
    assertMatch actual, expected, message

  # Assert that browser prompted with a given message.
  prompted: (messageShown, message)->

  # Asserts the selected element(s) has the expected value for the named style
  # property.
  style: (selector, style, expected, message)->
    if arguments.length == 2
      expected = null
    elements = @browser.queryAll(selector)
    assert elements.length > 0, "Expected selector '#{selector}' to return one or more elements"
    for element in elements
