Three types of form submits

I’m automating part of the the regression testing one of our sites using Selenium and had to use 3 different patterns within one small area of the system (login). Since I’ll likely have to explain to someone how to add to or maintain these scripts I figured I might as well write these patterns down for later reference. We’re a Ruby shop (though less than this time last year) so all examples are using the selenium-client gem.

  • Traditional Submit – This is the classic way of the web, since basically its inception. Stuff is passed to the server, the server does something, and the results are displayed via a page refresh.

    def test_both_blank
      @browser.open "/"
      @browser.click "//input[@name='commit' and @value='Login']", :wait_for => :page
      begin
        assert_equal "The email address or password was incorrect.", @browser.get_text("//div[@class='system_error']")
      rescue Test::Unit::AssertionFailedError
        @verification_errors << $!
      end
    end

    The only magic required here is the :wait_for => :page which does exactly what it implies; it waits for the page to refresh.

  • Internal Submit – This type is just manipulation of the DOM in the browser and nothing leaves that little sandbox. The classic example is when you have multiple forms on a page but you just change an attribute of it to show or hide it. This means you can’t wait for the page to load as it never unloads. Nor can you wait for an object to be present as it is, at least in the DOM. But you can check whether it is visible or not.

    def test_forgot_password_link
      @browser.open "/"
      @browser.click "link=exact:Forgot password?"
      @browser.wait_for_text('Enter your email address')
      begin
        assert_equal(false, @browser.visible?("//form[@id='login_frm']/fieldset/div[1]/input"))
        assert @browser.visible?("//form[@id='forgot_pwd_form']/fieldset/div[1]/input")
      rescue Test::Unit::AssertionFailedError
        @verification_errors << $!
      end
    end

    Here is am checking that both the thing that should no longer visible is indeed hidden and the bit that should be in its place is.

  • AJAX Submit – Of course, we are using AJAX (like everyone else) and I avoided it as long as I could, but ended up being nicely abstracted into the land of easiness. AJAX submits of course don’t refresh the page (like the Internal Submit) but contacts the server and displays the result (like the Traditional Submit).

    def test_forgot_password_no_email
      @browser.open "/"
      @browser.click "link=exact:Forgot password?"
      @browser.wait_for_text('Enter your email address')
      @browser.click "//input[@name='commit' and @value='Go']", :wait_for => :ajax
      begin
        assert_equal "That email address was not found.", @browser.get_text("//div[@class='system_error']")
      rescue Test::Unit::AssertionFailedError
        @verification_errors << $!
      end
    end

    Sweet! Wait for the the ajax request that happens as a result of the click and then continue. Now there is some serious black magic going on here. You can tweak it a bit with :javascript_framework => :jquery (or :prototype, but that is the default so you don’t really need to specify that) as an option on the click. Having to tag that on every AJAX action is a pain, so I’m getting my selenium connection like this now.

    @browser = Selenium::Client::Driver.new \
      :host => "localhost",
      :port => 4444,
      :browser => "*firefox",
      :url => "http://localhost:3000",
      :timeout => 10000,
      :javascript_framework => :jquery      
    @browser.start_new_browser_session

    One of our other sites uses both jquery and prototype so I would actually have to specify it on each line. Ah well.

Can anyone think of any other types of form submits?

Post a Comment

Your email is never published nor shared. Required fields are marked *