     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

  # If count is unspecified, defaults to at least one.
  elements: (selector, count, message)->
    elements = @browser.queryAll(selector)
    if count == undefined
      count = { atLeast: 1 }
    if count.exactly
      count = count.exactly


  # Asserts that selected input field (text field, text area, etc) has the expected value.
  input: (selector, expected, message)->
    if arguments.length == 1
      expected = null
    elements = @browser.queryAll(selector)
    assert elements.length > 0, "Expected selector '#{selector}' to return one or more elements"
    for element in elements
      assertMatch element.value, expected, message

  # Assert that text content of selected element(s) matches expected string.
  #
