<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>CheezyWorld</title>
	<atom:link href="http://www.cheezyworld.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.cheezyworld.com</link>
	<description>extremely cheezy</description>
	<lastBuildDate>Tue, 14 Feb 2012 10:57:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>page-object 0.5.4 released</title>
		<link>http://www.cheezyworld.com/2011/12/18/page-object-0-5-4-released/</link>
		<comments>http://www.cheezyworld.com/2011/12/18/page-object-0-5-4-released/#comments</comments>
		<pubDate>Sun, 18 Dec 2011 15:53:20 +0000</pubDate>
		<dc:creator>cheezy</dc:creator>
				<category><![CDATA[PageObject]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.cheezyworld.com/?p=1088</guid>
		<description><![CDATA[*** DEPRECATION WARNING *** You are calling a method named table. *** This method does not exist in page-object so it is being passed to the driver. *** This feature will be removed in the near future. *** Please change &#8230; <a href="http://www.cheezyworld.com/2011/12/18/page-object-0-5-4-released/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<pre>
<code>
*** DEPRECATION WARNING
*** You are calling a method named table.
*** This method does not exist in page-object so it is being passed to the driver.
*** This feature will be removed in the near future.
*** Please change your code to call the correct page-object method.
*** If you are using functionality that does not exist in page-object please request it be added.
</code>
</pre>
<p>You might see a warning similar to this one when you use the new page-object release.  I am planning on removing something that current exists in the gem.  This post will explain what and why.</p>
<p><span id="more-1088"></span></p>
<h3>What?</h3>
<p>When the page-object gem was young there was a significant amount of functionality that existed in the native drivers (watir-webdriver and selenium-webdriver) that was not exposed via the page-object gem.  At that time I decided to override <code>method_missing</code> in the <code>Element</code> class to directly delegate all unknown calls to the underlying native element.  This was a work around to make it easier for the users to use these capabilities while I was busy adding all necessary functionality into the page-object gem.</p>
<p>I will be removing this capability in about two months.  At that time you will get an error when you call a method on an <code>Element</code> that doesn&#8217;t exist.  The warning message should provide guidance to you on what you will need to change over the next two months.</p>
<h3>Why?</h3>
<p>Some of you may wonder why I am removing this feature.  While it seemed like a good idea at the time I added this capability, it has been the source of most of the support I have provided for users.  Many have found it confusing having both page-object and Watir calls mixed together and many errors resulted.  At this point, over three fourths of the problems I help people with are directly related to these calls being used together.  In almost every case the solution is to only use the page-object elements and methods.</p>
<h3>What should I do?</h3>
<p>You should run your scripts and note where these warnings occur.  When you see them you should adjust your code to use the page-object methods and objects.  If you do find that there is some feature you need that is currently not supported by page-object please go to the <a href="https://github.com/cheezy/page-object/issues?sort=created&#038;direction=desc&#038;state=open">issues page</a> and open an issue.  I will respond to it as soon as possible.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cheezyworld.com/2011/12/18/page-object-0-5-4-released/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Default Data Revisited</title>
		<link>http://www.cheezyworld.com/2011/12/11/default-data-revisited/</link>
		<comments>http://www.cheezyworld.com/2011/12/11/default-data-revisited/#comments</comments>
		<pubDate>Sun, 11 Dec 2011 21:10:51 +0000</pubDate>
		<dc:creator>cheezy</dc:creator>
				<category><![CDATA[Cucumber]]></category>
		<category><![CDATA[PageObject]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.cheezyworld.com/?p=1070</guid>
		<description><![CDATA[I just released a new version of the page-object gem today and it contains a nice new feature. This new feature will make it very easy to apply a set of data to a screen and have it populate all &#8230; <a href="http://www.cheezyworld.com/2011/12/11/default-data-revisited/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I just released a new version of the <code>page-object</code> gem today and it contains a nice new feature.  This new feature will make it very easy to apply a set of data to a screen and have it populate all of the fields.  This feature, when combined with a new gem I plan to announce soon, will allow for dynamic default data that can be used to drive a web application.  This data can be managed within the pages or externally.</p>
<p>This post is an actual section from chapter 5 of my book.  It introduces the concept of Default Data and also shows how to use this new feature.</p>
<p><span id="more-1070"></span></p>
<h3>High level tests</h3>
<p>Many of the <i>Scenarios</i> we have written so far suffer from a problem.  They are too verbose.  What I mean by this is they specify every single keystroke even when it is not important for the actual test.  Let’s take a look at the original <i>Scenario</i> where we adopted a puppy.</p>
<pre>
<code>
  Scenario: Adopting one puppy
    When I click the View Details button for “Brook”
    And I click the Adopt Me button
    And I click the Complete the Adoption button
    And I enter “Cheezy” in the name field
    And I enter “123 Main Street” in the address field
    And I enter “cheezy@example.com” in the email field
    And I select “Credit card” from the pay with dropdown
    And I click the Place Order button
    Then I should see “Thank you for adopting a puppy!”
</code>
</pre>
<p>What specifically are we verifying?  The only thing we are verifying is that the &#8220;Thank you&#8221; message is displayed.  Does it really matter what name I enter in the name field?  What about the puppy I select for adoption?</p>
<p>The truth is that none of the data I enter or select on the screens has any impact on the outcome for this particular <i>Scenario</i>.  That is also the case with most <i>Scenarios</i>.  Although we often have to enter a lot of information in order to complete a <i>Scenario</i> the majority of the information is not directly relevant for the thing we are testing. </p>
<p>A major part of writing good <i>Scenarios</i> is ensuring they are written well and easy to understand.  Imagine if we have to traverse through multiple pages to get to the page we plan to tests and each page requires us to enter a lot of data.  If we specify all of the typing and clicks in our <i>Scenario</i> there would be a lot of details.  It would be very easy to see how one could loose the simple items we wish to specify in all of those details.</p>
<p>Below is the same <i>Scenario</i> as above except all of the unnecessary details are hidden:</p>
<pre>
<code>
  Scenario: Thank you message should be displayed
    When I complete the adoption of a puppy
    Then I should see “Thank you for adopting a puppy!”
</code>
</pre>
<p>This <i>Scenario</i> is much easier to understand and we can clearly see what is being specified.  We still need to perform all of the activities necessary to adopt a puppy even though we did not specify them in the <i>Scenario</i>.  The next few sections will provide some techniques you can use to enable you to specify your <i>Scenarios</i> at a right level of granularity and still have all of the detailed steps take place.</p>
<h3>Inline Tables</h3>
<p>In chapter four we saw how we can build up a table of <i>Examples</i> to provide the data for a <i>Scenario Outline</i>.  It is also possible to have a table of data that is a part of an individual step.  Let&#8217;s see how would could place an order using a table of data.  We’ll make a modified version of the <i>Scenario</i> from the last section.</p>
<pre>
<code>
  Scenario: Adopting a puppy using a table
    When I click the View Details button for “Brook”
    And I click the Adopt Me button
    And I click the Complete the Adoption button
    And I complete the adoption with:
    | name   | address         | email              | pay_type |
    | Cheezy | 123 Main Street | cheezy@example.com | Check    |
    Then I should see “Thank you for adopting a puppy!”
</code>
</pre>
<p>In this case we&#8217;ve collapsed five steps into one.  Go ahead and write this <i>Scenario</i> and generate the one new step definition.  In this case we will be passing all of our test data to the page in one step.  When you generate you step definition you will notice that a table variable is passed into your step.  For our purposes we can just call a <code>hashes</code> method on table which will return an <code>Array</code> of <code>Hashes</code>.  Each entry in the <code>Array</code> represents one row of data with the key being the table header and the value being the data in the table.  Since we only have one row of data we will just call the <code>first</code> method on this <code>Array</code> to get the single <code>Hash</code> containing our data.</p>
<p>We have two options for the implementation.  The first option is to use the methods generated by <code>PageObject</code> like this:</p>
<pre class="brush: ruby; title: ; notranslate">
When /^I complete the adoption with:$/ do |table|
  data = table.hashes.first
  on_page(CheckoutPage) do |page|
    page.name = data['name']
    page.address = data['address']
    page.email = data['email']
    page.pay_type = data['pay_type']
    page.place_order
  end
end
</pre>
<p>Although this step definition works fine most of the code seems to be a little out of place in the step definition.  The knowledge of how to take a group of data, complete the form, and submit it would seem to be better place in the page object itself.  Let’s take a look how that might work.</p>
<p>Here is a new method on <code>CheckoutPage</code>:</p>
<pre class="brush: ruby; title: ; notranslate">
  def complete_order(data)
    self.name = data['name']
    self.address = data['address']
    self.email = data['email']
    self.pay_type = data['pay_type']
    place_order
  end
</pre>
<p>The first thing you might notice is that we are using the keyword <code>self</code> in our new method.  The reason for this is that equals methods (one that end with an equal sign) are required to have a receiver so they are not mistaken for local variable assignment.  <code>self</code> represents the current object and therefore when we call <code>self.name =</code> we are really saying call the <code>name=</code> method on this same object.</p>
<p>With this method on our page object our step definition can be simplified to this:</p>
<pre class="brush: ruby; title: ; notranslate">
When /^I complete the adoption with:$/ do |table|
  on_page(CheckoutPage).complete_order(table.hashes.first)
end
</pre>
<p><b>DO NOT OVERUSE TABLES</b><br />
Tables are nice and do help us consolidate multiple steps into one but they also make things a little harder to read.  Use you best judgement on when you believe it adds to the overall <i>Scenario</i> and make sure you do not overuse them to the point where it takes away from what we are trying to say.</p>
<h3>Default Data</h3>
<p>It is fairly common for your <i>Scenarios</i> to require a lot of data in order to complete a successful run.  In the last section we discussed how to use tables to create higher level tests.  In that <i>Scenario</i> it really didn’t matter if we used the name “Cheezy” or “Mickey Mouse”; the outcome would be the same.  In fact, none of the data we provide made any difference on the outcome.  As long as we select a puppy and complete the checkout form we see the thank you message.</p>
<p>We should ask ourselves why do we need to provide all of this data if it is not important to what we are testing.  Does providing this data really add clarity or is it distracting?  Does specifying every click necessary to traverse through the system add to our understanding?  Does it make the specification more complete?</p>
<p>If we were able to rephrase the <i>Scenario</i> from the last section to state the exact essence of what we were trying to specify it would be this:</p>
<pre>
<code>
  Scenario: Thank you message should be displayed
    When I complete the adoption of a puppy
    Then I should see “Thank you for adopting a puppy!”
</code>
</pre>
<p>This is much cleaner and easier to understand.  It specifies the exact thing we are trying to describe &#8211; a thank you message should be displayed when the adoption is completed.  </p>
<p>In order to implement the <i>Scenario</i> above we still need to provide the information necessary to fill in and submit the pages of our application.  But where will it come from?  This is where Default Data comes in.</p>
<p>Default Data is a widely used pattern in the testing community.  The pattern is implemented by providing a set of data that can be used to generically traverse through the application but at the same time allowing you to override any data specific to your context.  For example, take the last <i>Scenario</i>.  In that <i>Scenario</i> we should just be able to use the Default Data to complete all of the pages and the validate the message.  If required us to use a “Credit card” then we should be able to specify it override the default value and use “Credit card”.  Let’s see how we could implement this in our <code>CheckoutPage</code>.</p>
<pre class="brush: ruby; title: ; notranslate">
class CheckoutPage
  include PageObject

  DEFAULT_DATA = {
    ‘name’ =&gt; ‘cheezy’,
    ‘address’ =&gt; ‘123 Main Street’,
    ‘email’ =&gt; ‘cheezy@example.com’,
    ‘pay_type’ =&gt; ‘Purchase order’
  }

  text_field(:name, :id =&gt; “order_name”)
  text_field(:address, :id =&gt; “order_address”)
  text_field(:email, :id =&gt; “order_email”)
  select_list(:pay_type, :id =&gt; “order_pay_type”)
  button(:place_order, :value =&gt; “Place Order”)

  def complete_order(data = {})
    data = DEFAULT_DATA.merge(data)
    self.name = data['name']
    self.address = data['address']
    self.email = data['email']
    self.pay_type = data['pay_type']
    place_order
  end
end
</pre>
<p>There are several new things here to discuss.  The first is the <code>Hash</code> near the top of the class.  It simply provides the default data that will be used by the page.  The way this happens is that the first line of the <code>complete_order</code> method merges the data passed to the method with the default data of the page.  The merge simply tries to match up a key and if a match is found it will update the corresponding value.</p>
<p>The other new thing here is the modified parameter passed to our <code>complete_order</code> method &#8211; <code>data = {}</code>.  This is Rubies way of specifying a default parameter to a method.  If we provide a parameter when we call this method then it is passed on through.  If we call the method without passing a parameter the default will be used which is an empty <code>Hash</code> is this case.   The effect of using the empty <code>Hash</code> is to just use all of the default data.  </p>
<p>If you are using PageObject 0.5.3 or higher there is an even simpler way to populate your page with a <code>Hash</code> of data.  A new method has been added named <code>populate_page_with</code> which takes a <code>Hash</code>.  It will match up the keys from the <code>Hash</code> with the names you provided for the elements when you declared them on the page.  All values must be <code>Strings</code> except for Checkboxes and Radio Buttons must be <code>true</code> or <code>false</code>.  Let’s look at our complete_order method if we use this instead.</p>
<pre class="brush: ruby; title: ; notranslate">
When /^I complete the adoption using a Credit card$/ do
  on_page(CheckoutPage).complete_order(‘pay_type' =&gt; 'Credit card')
end

When /^I complete the adoption$/ do
  on_page(CheckoutPage).complete_order
end
</pre>
<p>I think we have achieved the goal of default data.  We can now individually set the values on the page using the methods generated by <code>page-object</code>.  We can use the default data by calling the <code>complete_order</code> method passing no parameters.  We can use partial or no default data by passing in a <code>Hash</code> that contains the data we wish to use.</p>
<p>The only additional page we have in our system where we have to provide data is the HomePage.  Providing default data for this page is as simple as providing a default parameter for the adopt method.</p>
<pre class="brush: ruby; title: ; notranslate">
def adopt(name = ‘Brook’)
  index = puppy_index_for(name)
  button_element(:value =&gt; 'View Details', :index =&gt; index).click
end
</pre>
<p>With this in place we can now get back and add the <i>Scenario</i> we introduced at the beginning of this section and add the missing step definition.</p>
<pre class="brush: ruby; title: ; notranslate">
When /^I complete the adoption of a puppy$/ do
  on_page(HomePage).adopt
  on_page(DetailsPage).adopt_me
  on_page(ShoppingCartPage).complete_adoption
  on_page(CheckoutPage).complete_order
end
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.cheezyworld.com/2011/12/11/default-data-revisited/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Playing the waiting game</title>
		<link>http://www.cheezyworld.com/2011/10/01/playing-the-waiting-game/</link>
		<comments>http://www.cheezyworld.com/2011/10/01/playing-the-waiting-game/#comments</comments>
		<pubDate>Sat, 01 Oct 2011 19:34:16 +0000</pubDate>
		<dc:creator>cheezy</dc:creator>
				<category><![CDATA[Cucumber]]></category>
		<category><![CDATA[PageObject]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.cheezyworld.com/?p=1009</guid>
		<description><![CDATA[One difficulty testers run into when they are new to driving browsers with cucumber is knowing how to handle sites that contain a lot of ajax calls. They write scripts that assume the elements on the page exist and are &#8230; <a href="http://www.cheezyworld.com/2011/10/01/playing-the-waiting-game/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>One difficulty testers run into when they are new to driving browsers with cucumber is knowing how to handle sites that contain a lot of ajax calls.  They write scripts that assume the elements on the page exist and are shocked when the tests fails because it was trying to access something that wasn&#8217;t on the page yet.</p>
<p>In this post I&#8217;ll write a simple scenario that demos the async handling capabilities in the <em>page-object</em> gem.  I&#8217;ll also briefly introduce you to a new gem that I use to generate my new projects.  I&#8217;ll do all of this by writing a scenario that uses one of the examples google has provided to demo the GWT libraries.  For those of you who have taken one of my classes you will already be familiar with this example but perhaps there are still a few things here for you to learn.  Let&#8217;s get started writing the code!</p>
<p><span id="more-1009"></span></p>
<h3>Creating the project</h3>
<p>The first thing I need to do is create my project structure.  Let me see.  I think I&#8217;ll use the <em>page-object</em> gem with <em>Selenium</em>.  Let&#8217;s use the <a href="https://github.com/cheezy/testgen">tesetgen</a> gem to get started.  If you don&#8217;t have this gem installed already you can just execute <code>gem install testgen</code>.  Here&#8217;s the command I used to generate my project:</p>
<pre><code>
testgen project ajax_example --pageobject-driver=selenium
</code></pre>
<p>This creates my entire project structure.  Let&#8217;s quickly verify that everything is OKay.  The first thing we need to do is make sure we have all of the gems installed.  <em>testgen</em> created a <code>Gemfile</code> file for us so all we need to do is change to the newly created ajax_example directory and execute <code>bundle install</code>.  </p>
<p>Now that we&#8217;re sure we have all of the gems installed it&#8217;s time to run cucumber.  <em>testgen</em> created a Rakefile for us to make that easy.  Just type the <code>rake</code> command in the ajax_example directory.  You should see the following:</p>
<pre><code>
Using the default profile...
0 scenarios
0 steps
0m0.000s
</code></pre>
<p>We&#8217;re now ready to write a scenario.</p>
<h3>Writing the scenario</h3>
<p>We&#8217;ll be using the DynaTable example from the GWT site.  <a href="http://gwt.google.com/samples/DynaTable/DynaTable.html">Here</a> is the page. On this page select a day checkbox and then the classes offered on that day are displayed in the row with the professors name.  Let&#8217;s try to write a scenario.</p>
<p>I start by creating a file in the features directory.  Here&#8217;s the content:</p>
<pre><code>
Feature: Displaying class schedules

I need to be able to display the class schedule for professors.  When I
select a day the page should display all of the class taught by professors
on that day as well as the time for the classes.

  Scenario: Displaying classes offered by professors
    Given I am on the google dynamic table page
    When I view the schedule for "Monday"
    Then I should see that "Inman Mendez" offers a class at "Mon 9:45-10:35"
    When I view the schedule for "Tuesday"
    Then I should see that "Inman Mendez" offers a class at "Tues 2:15-3:05"
    And I should see that "Teddy Gibbs" offers a class at "Tues 10:00-10:50"
</code></pre>
<p>Notice that I didn&#8217;t say anything about clicking buttons or checkboxes.  Also notice that I in no way stated how the class or instructor&#8217;s name are found or represented on the page.  Why do you think I did this?  I&#8217;ll have a lot more to say about this in future posts.</p>
<p>My next step is to create the step definitions.  To do this I will again execute the &#8216;rake&#8217; command.  Cucumber is nice enough to generate the pending step definitions.</p>
<pre class="brush: ruby; title: ; notranslate">
Given /^I am on the google dynamic table page$/ do
  pending # express the regexp above with the code you wish you had
end

When /^I view the schedule for &quot;([^\&quot;]*)&quot;$/ do |arg1|
  pending # express the regexp above with the code you wish you had
end

Then /^I should see that &quot;([^\&quot;]*)&quot; offers a class at &quot;([^\&quot;]*)&quot;$/ do |arg1, arg2|
  pending # express the regexp above with the code you wish you had
end
</pre>
<p>I know I&#8217;m going to create a page object but first of all I want to think about what that object will look like.  I think I&#8217;ll write the code I wish I had in a couple of the step definitions.  Here&#8217;s what I came up with:</p>
<pre class="brush: ruby; title: ; notranslate">
When /^I view the schedule for &quot;([^\&quot;]*)&quot;$/ do |day|
  page.select_schedule_for day
end

Then /^I should see that &quot;([^\&quot;]*)&quot; offers a class at &quot;([^\&quot;]*)&quot;$/ do |name, expected|
  page.schedule_for(name).include? expected
end
</pre>
</pre>
<p></code></p>
<p>Yeah.  I think that's how I want to interact with the page object.  These step definitions are not complete.  I have just written enough to understand what I need to include in the page object I am about to write.  Now, let's write it.</p>
<h3>Creating the Page Object</h3>
<p>In order to implement the functionality I currently need in my page object I will need to provide access to the day checkboxes, the none button (in order to clear all of the checkboxes), and the table that contains the schedules.  I'll also need to provide the url for the page. I create a new file in the <code>pages</code> directory named <code>dynamic_table_page.rb</code>.  Here's the first version of this class:</p>
<pre class="brush: ruby; title: ; notranslate">
class DynamicTablePage
  include PageObject

  page_url &quot;http://gwt.google.com/samples/DynaTable/DynaTable.html&quot;
  table(:dyna_table, :class =&gt; 'table')
  checkbox(:sunday, :id =&gt; 'gwt-uid-1')
  checkbox(:monday, :id =&gt; 'gwt-uid-2')
  checkbox(:tuesday, :id =&gt; 'gwt-uid-3')
  checkbox(:wednesday, :id =&gt; 'gwt-uid-4')
  checkbox(:thursday, :id =&gt; 'gwt-uid-5')
  checkbox(:friday, :id =&gt; 'gwt-uid-6')
  checkbox(:saturday, :id =&gt; 'gwt-uid-7')
  button(:none, :value =&gt; 'None')

end
</pre>
<p>The next thing I need to do is write the two methods I determined I needed earlier.  Here they are:</p>
<pre class="brush: ruby; title: ; notranslate">
def select_schedule_for(day)
  none
  self.send &quot;check_#{day.downcase}&quot;
end

def schedule_for(name)
  the_row = dyna_table_element.find { |row| row[0].text == name}
  the_row[2].text
end
</pre>
<p>I think there are a few things here that need explaining.  Let's take it one method at a time.</p>
<h4>Sending messages</h4>
<p>In the first method we are pressing the <em>none</em> button which clears all of the checkboxes.  Next we check the appropriate checkbox.  The <em>page-object</em> gem generates four methods when you define a checkbox.  Let's look at the four methods generated for the <code>:monday</code> checkbox declaration above.</p>
<pre class="brush: ruby; title: ; notranslate">
def check_monday
  # check the monday checkbox
end

def uncheck_monday
  # uncheck the monday checkbox
end

def monday_checked?
  # return whether the monday checkbox is checked
end

def monday_element
  # return the monday checkbox element
end
</pre>
<p>Understanding the generated methods it makes it clear that what we want to call is the <code>check_?</code> method.  When you call a method in Ruby it actually sends a message to the object on which the call is to be made.  In fact, Ruby provides a <code>send</code> method that performs the actual call.  In other words:</p>
<pre class="brush: ruby; title: ; notranslate">
page.check_monday

# is the same as

page.send &quot;check_monday&quot;
</pre>
<p>This is what allows us to call the appropriate checkbox method based on the name passed into the method.  Notice that we force the day name to lowercase so "Monday" as an argument yields <code>check_monday</code>.</p>
<pre class="brush: ruby; title: ; notranslate">
def select_schedule_for(day)
  none
  self.send &quot;check_#{day.downcase}&quot;
end
</pre>
<h4>Allow me to Enumerate</h4>
<p>Ruby has a module mixin named <a href="http://www.ruby-doc.org/core/classes/Enumerable.html">Enumerable</a>.  The numerous methods provided by this module add the ability to traverse, search, and sort items in a collection.  In the <em>page-object</em> gem the <code>Table</code>, <code>TableRow</code>, <code>OrderedList</code>, and <code>UnorderedList</code> elements all include Enumerable.  This provides the ability to perform activities on their children.  For example, you can loop through all of the <code>TableRow</code> elements by using the methods on <code>Table</code> and then you can loop through the <code>TableCell</code> elements by calling the methods on <code>TableRow</code>.</p>
<p>We use one of the methods from <code>Enumerable</code> to help us find the correct row in the table.  The <code>find</code> method calls a block one time for each item in the list.  The method will return the first item in which the block returns true.  We can look for the name of the professor by looking at the first column of the table.</p>
<pre class="brush: ruby; title: ; notranslate">
def schedule_for(name)
  the_row = dyna_table_element.find { |row| row[0].text == name}
  the_row[2].text
end
</pre>
<p>The final thing we need to do is return the text from the third row column which contains the courses offered.</p>
<h4>Getting rid of the magic</h4>
<p>The final change I wish to make to the page object is to eliminate the magic numbers.  Magic numbers are numbers that appear in code that have a significance but their meaning is not obvious.  For example, we are using 0 and 2 in the <code>schedule_for</code> method.  If I come back to this code several months after writing it I am sure I will not remember exactly what those numbers mean.  To resolve this I will add constants that provide some meaning.  After making that change you can see the entire class.</p>
<pre class="brush: ruby; title: ; notranslate">
class DynamicTablePage
  include PageObject

  NAME_COLUMN = 0
  SCHEDULE_COLUMN = 2

  page_url &quot;http://gwt.google.com/samples/DynaTable/DynaTable.html&quot;
  table(:dyna_table, :class =&gt; 'table')
  checkbox(:sunday, :id =&gt; 'gwt-uid-1')
  checkbox(:monday, :id =&gt; 'gwt-uid-2')
  checkbox(:tuesday, :id =&gt; 'gwt-uid-3')
  checkbox(:wednesday, :id =&gt; 'gwt-uid-4')
  checkbox(:thursday, :id =&gt; 'gwt-uid-5')
  checkbox(:friday, :id =&gt; 'gwt-uid-6')
  checkbox(:saturday, :id =&gt; 'gwt-uid-7')
  button(:none, :value =&gt; 'None')

  def select_schedule_for(day)
    none
    self.send &quot;check_#{day.downcase}&quot;
  end

  def schedule_for(name)
    the_row = dyna_table_element.find { |row| row[NAME_COLUMN].text == name}
    the_row[SCHEDULE_COLUMN].text
  end
end
</pre>
<h3>Finishing the Step Definitions</h3>
<p>I can now finish the step definitions.  I'll be using the <a href="https://github.com/cheezy/page-object/wiki/Creating-and-using-page-objects">PageObject::PageFactory</a> to create my objects.  Let's look at the steps and then we can discuss the details.</p>
<pre class="brush: ruby; title: ; notranslate">*)&quot;$/ do |day|
  on_page(DynamicTablePage).select_schedule_for day
end

Then /^I should see that &quot;([^\&quot;]*)&quot; offers a class at &quot;([^\&quot;]*)&quot;$/ do |name, expected|
  on_page(DynamicTablePage) do |page|
    page.wait_until(2) do
      page.schedule_for(name).include? expected
    end
  end
end
</pre>
<p>The third step beginning on line nine is where the ajax heavy lifting occurs.  I am using the <code>wait_until</code> method available on <code>PageObject</code>.  There are numerous <a href="https://github.com/cheezy/page-object/wiki/Ajax-Calls">methods to handle ajax calls</a> baked into the gem.  This particular method will wait until the block returns true.  By default it will wait for 30 seconds but I thought that was too long so I am passing in 2 to set the wait time to 2 seconds.  If the expected text for the schedule does not show up within 2 seconds an error will be thrown and the step will fail.</p>
<h3>Wrapping up</h3>
<p>Please take the time to look at the <a href="https://github.com/cheezy/page-object/wiki/Ajax-Calls">other methods</a> that <em>page-object</em> provides that make testing ajax sites simple.  As always, please let me know what you think of this post.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cheezyworld.com/2011/10/01/playing-the-waiting-game/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Running your Cukes in Jenkins</title>
		<link>http://www.cheezyworld.com/2011/08/09/running-your-cukes-in-jenkins/</link>
		<comments>http://www.cheezyworld.com/2011/08/09/running-your-cukes-in-jenkins/#comments</comments>
		<pubDate>Tue, 09 Aug 2011 23:28:54 +0000</pubDate>
		<dc:creator>cheezy</dc:creator>
				<category><![CDATA[Cucumber]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.cheezyworld.com/?p=926</guid>
		<description><![CDATA[One question that I am often asked is &#8220;How do you run your cucumber scripts?&#8221;. This question usually leads to a discussion about what process and software I use to run my features in a regression-like fashion in a team &#8230; <a href="http://www.cheezyworld.com/2011/08/09/running-your-cukes-in-jenkins/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>One question that I am often asked is &#8220;How do you run your cucumber scripts?&#8221;.  This question usually leads to a discussion about what process and software I use to run my features in a regression-like fashion in a team setting.  The questioners are usually not interested in how a developer might use <a href="http://www.zenspider.com/ZSS/Products/ZenTest/">autotest</a> (my local tool of choice) to run the cuke/spec loop.  They&#8217;re not interested in how a developer might run a feature on their local machine to verify they have completed a card.  They&#8217;re also not interested in how a developer or tester might run the entire suite of features to verify everything still works. They want to know how to schedule the execution of the entire suite of features.</p>
<p>The truth is that I don&#8217;t run them.  Instead I have a server process run the features for me.  I am a strong advocate of having the <a href="http://martinfowler.com/articles/continuousIntegration.html">continuous integration</a> server run the acceptance tests continuously.  This post will explain how I do it and hopefully provide you the information you need to do it as well.</p>
<p><span id="more-926"></span></p>
<h3>Let&#8217;s be clear</h3>
<p>Before I go into the details let me be clear.  I am not proposing that this is the only way you and your team should run your features.  I am a proponent of developers running the feature they are working on all of the time (perhaps continuously) and I think testers should run them on their computer very frequently as well.  This post is about how I like to run the entire suite of features to form a regression.  I&#8217;ll start by introducing how I control the running of the features and setup my projects.  Next I&#8217;ll discuss how this works with Jenkins.</p>
<h3>cucumber.yml</h3>
<p>First of all I have a <a href="https://github.com/cucumber/cucumber/wiki/cucumber.yml">cucumber.yml</a> file at the root of my project structure.  I use this file to define a set of profiles (a grouping of command-line arguments) that I can easily use when I want to run my features.  Cucumber already has a <code>default</code> profile that will be used unless you override it.  Here is what that might look like:</p>
<pre><code>
default:  --no-source --format pretty --tags ~@not_ready
</code></pre>
<p>Everything after the <code>default:</code> label in the entry will be passed to cucumber as arguments when it runs.  </p>
<p>You can use profiles to define separate definitions of how you want to run your features.  For example, if you have some very slow tests you might want to separate them out into their own run.  You would start by placing a <code>@slow</code> tag on those features or scenarios and then create a few profiles like this:</p>
<pre><code>
default:  --no-source --format pretty --tags ~@not_ready
slow:  --no-source --format pretty --tags @slow --tags ~@not_ready
fast:  --no-source --format pretty --tags @~slow, ~@not_ready
</code></pre>
<p>To use the profiles you simply pass the profile name on the command line.  If you wish to run the fast tests you would run:</p>
<pre><code>
cucumber -p fast
</code></pre>
<h3>Rakefile</h3>
<p>Rake is a tool that has the ability to execute tasks.  Many tools, including cucumber, are distributed with pre-built rake tasks that can be used to control their execution.  Jenkins has a plugin that can execute Rakefiles.  We use this combination to control the running of our features in Jenkins.  We will discuss how to setup Jenkins in the next section.  Here we&#8217;ll discuss how to write a simple Rakefile.  Let&#8217;s start by looking at a simple example.</p>
<p><code></p>
<pre class="brush:ruby">
require ‘cucumber’
require ‘cucumber/rake/task’

Cucumber::Rake::Task.new(:features) do |t|
  t.profile = ‘ci’
end

task :default => :features
</pre>
<p></code></p>
<p>This rake script creates a new task named <code>features</code> and has it call the ci profile.  Next it makes the features task the default task.  You can execute <code>rake</code> in the project directory and it will run the <code>features</code> task (the default) using the <code>ci</code> profile created in a <code>cucumber.yml</code> file.  We use the Rakefile to specify which profile to run and we use the cucumber.yml file to detail out the profiles.</p>
<p>A more sophisticated Rakefile might create a namespace to contain several tasks.</p>
<p><code></p>
<pre class="brush:ruby">
require ‘cucumber’
require ‘cucumber/rake/task’

namespace :features do
  Cucumber::Rake::Task.new(:fast) do |t|
    t.profile = ‘fast’
  end

  Cucumber::Rake::Task.new(:slow) do |t|
    t.profile = ‘slow’
  end

  task :ci => [:fast, :slow]
end

task :default => :fast
</pre>
<p></code></p>
<p>This Rakefile creates a namespace named <code>features</code>, which contains three tasks (fast, slow, and ci).  The ci task runs the fast task followed by the slow task.  To execute the slow tests you would execute </p>
<pre><code>
rake features:slow.
</code></pre>
<p>If you want to see what tasks are available from the rake tool you can execute the <code>rake –T</code> command.</p>
<h3>Jenkins</h3>
<p>The Jenkins configuration couldn&#8217;t be simpler.  The first thing you need to do is install the <code>Jenkins Rake plugin</code>.  Once this is installed you should go to the <code>Configure System</code> page.  You will see a new section appear on this page.</p>
<p><a href="http://www.cheezyworld.com/wp-content/uploads/2011/08/rake_config.png"><img src="http://www.cheezyworld.com/wp-content/uploads/2011/08/rake_config.png" alt="" title="rake_config" width="845" height="193" class="aligncenter size-full wp-image-994" /></a></p>
<p>It is likely that Jenkins discovered your ruby installation already but if it didn&#8217;t, just enter the path to the location where ruby is installed.</p>
<p>Next you need to create the project to run your cukes.  Complete the form as you usually would.  In the <code>Build</code> section select the <code>Add build step</code> button and then select <code>Invoke Rake</code>.  This will open this dialog.</p>
<p><a href="http://www.cheezyworld.com/wp-content/uploads/2011/08/invoke_rake.png"><img src="http://www.cheezyworld.com/wp-content/uploads/2011/08/invoke_rake.png" alt="" title="invoke_rake" width="809" height="209" class="aligncenter size-full wp-image-997" /></a></p>
<p>In this section you simply need to type the task you wish to run.</p>
<h3>Guidelines I use to run my cukes</h3>
<p>How often should you run your features?  In my opinion, you should try to run them as close to all of the time as possible.  Each time they run they should execute against the latest version of the application.</p>
<p>If it takes 2 hours 30 minutes to run the tests I would schedule them to run every 3 hours.  If you have some slow tests you might want to schedule them to run 4 times a day and have the fast test run every hour.</p>
<p>The goal here is to get fast feedback.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cheezyworld.com/2011/08/09/running-your-cukes-in-jenkins/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Those pesky frames and iframes</title>
		<link>http://www.cheezyworld.com/2011/08/08/those-pesky-frames-and-iframes/</link>
		<comments>http://www.cheezyworld.com/2011/08/08/those-pesky-frames-and-iframes/#comments</comments>
		<pubDate>Mon, 08 Aug 2011 16:54:03 +0000</pubDate>
		<dc:creator>cheezy</dc:creator>
				<category><![CDATA[Cucumber]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.cheezyworld.com/?p=970</guid>
		<description><![CDATA[Wouldn&#8217;t it be sweet if all of the web pages in the world were nicely formed with easy to identify elements. If you work in an environment like this, I am envious. I often find myself working with a team &#8230; <a href="http://www.cheezyworld.com/2011/08/08/those-pesky-frames-and-iframes/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Wouldn&#8217;t it be sweet if all of the web pages in the world were nicely formed with easy to identify elements.  If you work in an environment like this, I am envious.  I often find myself working with a team where the sites are not pristine (I&#8217;m being nice here).</p>
<p>One thing I have found difficult to work with is pages that have frames and iframes.  It gets worse when the elements you are trying to work with are nested within multiple frames/iframes.  To address this complexity I decided to add simple frames handling to page-object.  </p>
<p><span id="more-970"></span></p>
<p>The page-object gem provides a way to declare elements are within frames or iframes.  In fact, these frames can be nested infinitely.  Let&#8217;s look at a simple case.</p>
<p><code></p>
<pre class="brush:ruby">
class RegistrationPage
  include PageObject

  in_frame(:id => 'left-frame') do |frame|
    text_field(:address, :id => 'address_id', :frame => frame)
  end
end
</pre>
<p></code></p>
<p>In this example we are declaring that the textfield exists within a frame identified by the id &#8216;left-frame&#8217;.  Note that I am passing the frame argument for the block as the last parameter to <code>text_field</code>.  In the remainder of my class I can just refer to the element by its&#8217; name &#8211; in this case &#8216;address&#8217;.</p>
<p>Frames can be identified by <code>:name</code>, <code>:id</code>, or <code>:index</code> and frames and iframes are handled identically.</p>
<p>Let&#8217;s take a look at how we would handle a situation where the frames (or iframes) are nested within other frames. We&#8217;ll modify the example above.</p>
<p><code></p>
<pre class="brush:ruby">
class RegistrationPage
  include PageObject

  in_frame(:id => 'left-frame') do |frame|
    in_frame({:id => 'left-top-frame'}, frame) do |frame|
      text_field(:address, :id => 'address_id', :frame => frame)
    end
  end
end
</pre>
<p></code></p>
<p>There are a couple of interesting things here.  First of all we just nested our previous call to <code>in_frame</code> in another call to the same method.  Also note that we had to pass the frame block parameter from the first call to the second call to <code>in_frame</code>.  This method is how <code>page-object</code> keeps track of the frame nesting and allows you to nest calls to <code>in_frame</code> as many times as necessary.</p>
<p>That&#8217;s all there is to it.  Enjoy.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cheezyworld.com/2011/08/08/those-pesky-frames-and-iframes/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Introducing page-object gem</title>
		<link>http://www.cheezyworld.com/2011/07/29/introducing-page-object-gem/</link>
		<comments>http://www.cheezyworld.com/2011/07/29/introducing-page-object-gem/#comments</comments>
		<pubDate>Fri, 29 Jul 2011 23:14:02 +0000</pubDate>
		<dc:creator>cheezy</dc:creator>
				<category><![CDATA[Cucumber]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.cheezyworld.com/?p=946</guid>
		<description><![CDATA[page-object is a simple ruby gem that assists in creating flexible page objects for testing browser based applications. To understand the inspiration for this gem please read this blog post. This post will walk you through some of the core &#8230; <a href="http://www.cheezyworld.com/2011/07/29/introducing-page-object-gem/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="https://github.com/cheezy/page-object">page-object</a> is a simple ruby gem that assists in creating flexible page objects for testing browser based applications.  To understand the inspiration for this gem please read <a href="http://www.cheezyworld.com/2010/11/19/ui-tests-introducing-a-simple-dsl/">this blog post</a>.  </p>
<p>This post will walk you through some of the core features of the gem.  Most of the materials in this post are also on the <a href="https://github.com/cheezy/page-object/wiki/page-object">project wiki</a>.  Please refer to the wiki for updated documentation.</p>
<p><span id="more-946"></span></p>
<h2>Get me started right now!</h2>
<p>For the impatient among you we will get directly to showing you how to use it.</p>
<h3>Create your page</h3>
<p>The first thing you must do is create your page objects.  These are simple ruby classes that include the <code>PageObject</code> Module.</p>
<p><code></p>
<pre class="brush:ruby">
class RegistrationPage
  include PageObject
end
</pre>
<p></code></p>
<p>By including the <code>PageObject</code> Module you have added a lot of capabilities to your page.  Let&#8217;s take a look at how we might use some of that right now.</p>
<h3>Describe your page</h3>
<p>After you create your page object class you need to describe the web page this class represents.  The <code>RegistrationPage</code> example might look like this:</p>
<p><code></p>
<pre class="brush:ruby">
class RegistrationPage
  include PageObject

  text_field(:name, :id => 'name')
  text_field(:email, :id => 'email')
  button(:register, :value => 'Register')
end
</pre>
<p></code></p>
<p>By calling these methods, the <code>PageObject</code> Module will add several additional methods for you.  To learn about what methods are available and what methods they generate please see <a href="http://rubydoc.info/github/cheezy/page-object/master/PageObject/Accessors">this page</a>.</p>
<h3>Use your page</h3>
<p>Now that we have a basic page object defined it is time to put it to use.  You can use either <a href="https://rubygems.org/gems/watir-webdriver">watir-webdriver</a> or <a href="https://rubygems.org/gems/selenium-webdriver">selenium-webdriver</a> as the driver gem.  Just pass them into the constructor.</p>
<p><code></p>
<pre class="brush:ruby">
browser = Watir::Browser.new :firefox
registration_page = RegistrationPage.new(browser)
</pre>
<p></code></p>
<p>or</p>
<p><code></p>
<pre class="brush:ruby">
browser = Selenium::WebDriver.for :firefox
registration_page = RegistrationPage.new(browser)
</pre>
<p></code></p>
<p>Once created, you can interact with the page using the generated methods.</p>
<p><code></p>
<pre class="brush:ruby">
registration_page.name = 'Test User'
registration_page.email = 'test@example.com'
registration_page.register
</pre>
<p></code></p>
<p>That&#8217;s all there is to getting started with the gem.  The good news is that there is a lot of additional functionality that was not covered in this brief introduction.  Continue reading to learn more.</p>
<h2>Page-Object Features</h3>
<p>Here are a few of the features you will find in this gem:</p>
<h3>A simple DSL for defining and interacting with the content of your page</h3>
<p>The <code>PageObject</code> Module adds several methods to your page object.  The methods that are added follow a similar pattern.  Let&#8217;s take a look at a few of the methods and their generated output.</p>
<p>The call to <code>text_field</code> like this one</p>
<p><code></p>
<pre class="brush:ruby">
text_field(:first_name, :id => 'first')
</pre>
<p></code></p>
<p>will produce the following three methods</p>
<p><code></p>
<pre class="brush:ruby">
first_name               # return the value in the text field
first_name=              # set the value in the text field
first_name_element       # return the text field element
</pre>
<p></code></p>
<p>There is one special purpose generator method that does not follow this pattern. When you call the <code>page_url</code> method</p>
<p><code></p>
<pre class="brush:ruby">
page_url 'http://google.com'
</pre>
<p></code></p>
<p>it will produce a method named <code>goto</code>.  To see all of the methods available and what methods the generated read the documentation for the <code>Accessors</code> module <a href="http://rubydoc.info/github/cheezy/page-object/master/PageObject/Accessors">here</a>.</p>
<h3>Support for both watir-webdriver and selenium-webdriver</h3>
<p>The <code>page-object</code> gem can use either <a href="https://rubygems.org/gems/watir-webdriver">watir-webdriver</a> or <a href="https://rubygems.org/gems/selenium-webdriver">selenium-webdriver</a> as the underlying gem to drive the browser.  The way you choose which driver to use is by passing it into the constructor of your <code>PageObject</code></p>
<p><code></p>
<pre class="brush:ruby">
browser = Watir::Browser.new :firefox
registration_page = RegistrationPage.new(browser)
</pre>
<p></code></p>
<p>or</p>
<p><code></p>
<pre class="brush:ruby">
browser = Selenium::WebDriver.for :firefox
registration_page = RegistrationPage.new(browser)
</pre>
<p></code></p>
<p>In order to make this work seamlessly, the <code>page-object</code> gem had to add capabilities found in one driver and not in the other.  Let&#8217;s look at one example.</p>
<h4>Locating elements</h4>
<p>There were differences in the way Watir and Selenium allowed you to locate elements on a page.  We had to add functionality to <code>page-object</code> to eliminate those differences.  Here are a few notable ones:</p>
<ul>
<li>Watir allows you to provide multiple locators when identifying an element on a page.  Selenium only allows you to provide one locator.  With <code>page-object</code> you can now use multiple parameters when using Selenium.</li>
<li>Watir provides the ability to use <code>:index</code> when locating an element.  Selenium did not have this capability.  With <code>page-object</code> you can now use <code>:index</code> when using Selenium.</li>
<li>In Selenium you could not find a link by <code>:href</code> while this ability existed in Watir.  With <code>page-object</code> on Selenium you can now use <code>:href</code> when identifying a link.</li>
<li>Watir supports finding a hidden field by <code>:text</code>.  This ability does not exist in Selenium.  With <code>page-object</code> you can find a hidden field by <code>:text</code> when using Selenium.</li>
<li>What did not support finding div, span, table, table data, ordered lists, unordered lists, and list items by <code>:name</code>.  Selenium had this ability.  With <code>page-object</code> you can now find these elements using <code>:name</code>.</li>
</ul>
<h3>Creating and using page objects</h3>
<p>Alister Scott <a href="http://watirmelon.com/2011/06/07/removing-local-page-references-from-cucumber-steps/">blogged</a> about an idea for creating a factory to create instances of page objects.  In the past I have blogged about <a href="http://www.cheezyworld.com/2010/11/13/ui-tests-part-two/">page objects returning page objects</a>.  After a lot of contemplation, I am completely in the Alister camp.  <code>page-object</code> now supports this approach as well.</p>
<h4>PageFactory</h4>
<p>A module named <code>PageFactory</code> provides this ability.  This module has two methods.</p>
<p><code></p>
<pre class="brush:ruby">
def visit_page(page_class, &#038;block)
def on_page(page_class, visit=false, &#038;block)
</pre>
<p></code></p>
<p>Let&#8217;s take a look at how you would use these methods in your cucumber scripts.</p>
<p><code></p>
<pre class="brush:ruby">
Given /^I am on the registration page$/ do
  visit_page RegistrationPage
end
</pre>
<p></code></p>
<p>This call will cause the browser to open the page specified by the call to <code>page_url</code> in the class.</p>
<p><code></p>
<pre class="brush:ruby">
class RegistrationPage
  include PageObject

  page_url "http://mysite.com/registration"
  ...
end
</pre>
<p></code></p>
<p>If you wish to perform some activity on that page when you navigate to it you can pass a block to the method.</p>
<p><code></p>
<pre class="brush:ruby">
When /^I register on the registration page$/ do
  visit_page RegistrationPage do |page|
    page.register_user
  end
end
</pre>
<p></code></p>
<p>If you are already on a page and wish to interact with it you can use the <code>on_page</code> method.</p>
<p><code></p>
<pre class="brush:ruby">
Then /^I should be able to cancel my order$/ do
  on_page CheckoutPage do |page|
    page.cancel_order
  end
end
</pre>
<p></code></p>
<h3>Handling Ajax calls</h3>
<p>The secret to working with Ajax is having the ability to wait until different page events occur.  The <code>page-object</code> gem supports waiting at two different levels &#8211; the page level and the element level.  Let&#8217;s look at both.</p>
<h4>Page level waiting</h4>
<p>On the <code>PageObject</code> module (and therefore on your page objects) there is a method that assist with waiting.</p>
<p><code></p>
<pre class="brush:ruby">
def wait_until(timeout=30, message=nil, &#038;block)
</pre>
<p></code></p>
<p>This method will wait until the passed in block returns true.  If the block does not return true within the specified <code>timeout</code> seconds then an error is thrown with a default message or the provided <code>message</code>.  Let&#8217;s take a look at how we might use this.</p>
<p><code></p>
<pre class="brush:ruby">
@page.wait_until do
  @page.text.include? "Success"
end
</pre>
<p></code></p>
<p>In this example we are using the default <code>timeout</code> and <code>message</code>.  This code will wait until the page includes the text &#8220;Success&#8221;.  Let&#8217;s look at another example.</p>
<p><code></p>
<pre class="brush:ruby">
@page.wait_until(5, "Call not returned within 5 seconds") do
  @page.text.include? "Value returned from Ajax call"
end
</pre>
<p></code></p>
<p>In this example we are setting the <code>timeout</code> to 5 seconds and providing a custom <code>message</code>.</p>
<h4>Element level waiting</h4>
<p>On the <code>Element</code> class we have several methods to assist with waiting.</p>
<p><code></p>
<pre class="brush:ruby">
def when_present(timeout=5)
def when_visible(timeout=5)
def when_not_visible(timeout=5)
def wait_until(timeout=5, message=nil, &#038;block)
</pre>
<p></code></p>
<p>The usage of the first three methods are fairly self explanatory.  They will simply wait until the element is present, visible, or not visible and then continue.  If the wait exceeds the <code>timeout</code> value then an error occurs.  Let&#8217;s look at a simple example.</p>
<p><code></p>
<pre class="brush:ruby">
@page.continue_element.when_visible do
  @page.continue
end
</pre>
<p></code></p>
<p>As of release 0.3.2 you can combine these into a single call like this:</p>
<p><code></p>
<pre class="brush:ruby">
@page.continue_element.when_visible.continue
</pre>
<p></code></p>
<p>In this code we are waiting until a link defined by a call to <code>link(:continue, :id => 'cont')</code> is visible and then we are clicking it.</p>
<p>There are times when you want to wait for something other than the element being present or visible.  The last wait call <code>wait_until</code> handles this well.  It will wait until the block returns true.</p>
<h3>Handling JavaScript popups</h3>
<p>Handling JavaScript popups in Watir and Selenium has always been a hassle.  The approach the <code>page-object</code> gem takes is to intercept the call to the popup and cause it to not happen.  At the same time, the gem provides the information to the user that they would wish to receive if they had access to the popup.  Let&#8217;s look at a few examples.</p>
<h4>Alerts</h4>
<p>The <code>PageObject</code> module has a method named <code>alert</code>.  Her&#8217;s how you can use it.</p>
<p><code></p>
<pre class="brush:ruby">
message = @page.alert do
  @page.button_that_cases_the_alert
end
message.should == "My Alert!"
</pre>
<p></code></p>
<p>This call demonstrates that we are passing a block to the <code>alert</code> method.  That block is the code that causes the alert to occur.  The alert will not popup but the message that was included in the popup is returned by the block.</p>
<h4>Confirms</h4>
<p><code>PageObject</code> also has a <code>confirm</code> method that handles confirm popups.  It works the same way as the <code>alert</code> method except it requires a boolean parameter which is the value returned to the browser when the confirm popup is called.  Here&#8217;s an example.</p>
<p><code></p>
<pre class="brush:ruby">
message = @page.confirm(true) do
  @page.button_causing_the_confirm
end
</pre>
<p></code></p>
<h4>Prompts</h4>
<p>Finally, <code>PageObject</code> has a <code>prompt</code> method that follows the same pattern.  There are two differences.  The first is that it accepts a parameter that is the value returned from the prompt.  The second is that it returns a <code>Hash</code> with two keys &#8211; <code>:message</code> contains the message from the confirm popup and <code>:default_value</code> contains the default value if one was provided.</p>
<p><code></p>
<pre class="brush:ruby">
confirm_result = @page.prompt("Cheese") do
  @page.what_do_you_like_button
end
confirm_result[:message].should == "What do you like?"
</pre>
<p></code></p>
<h2>Additional documentation</h2>
<p>You can read the RDoc documentation <a href="http://rubydoc.info/github/cheezy/page-object/master/frames">here</a>.</p>
<p>The ChangeLog with the gem&#8217;s history can be found <a href="https://raw.github.com/cheezy/page-object/master/ChangeLog">here</a>.</p>
<h2>Requesting features and reporting issues</h2>
<p>The project has an <a href="https://github.com/cheezy/page-object/issues">Issues</a> tracker where you can request new functionality and report defects.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cheezyworld.com/2011/07/29/introducing-page-object-gem/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Transforming My Cukes</title>
		<link>http://www.cheezyworld.com/2011/02/20/transforming-my-cukes/</link>
		<comments>http://www.cheezyworld.com/2011/02/20/transforming-my-cukes/#comments</comments>
		<pubDate>Sun, 20 Feb 2011 18:11:04 +0000</pubDate>
		<dc:creator>cheezy</dc:creator>
				<category><![CDATA[Cucumber]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.cheezyworld.com/?p=850</guid>
		<description><![CDATA[This past week on the cucumber list Aslak asked if people knew about and where using Transforms. Based on the response I would have to say that not many know about it. I have to put myself in this category. &#8230; <a href="http://www.cheezyworld.com/2011/02/20/transforming-my-cukes/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This past week on the <a href="http://groups.google.com/group/cukes?hl=en">cucumber list</a> Aslak <a href="http://groups.google.com/group/cukes/browse_thread/thread/89c537449b74e7a4?hl=en">asked</a>  if people knew about and where using <a href="https://github.com/aslakhellesoy/cucumber/wiki/Step-Argument-Transforms">Transforms</a>.  Based on the response I would have to say that not many know about it.  I have to put myself in this category.  I decided to dig in and here is what I&#8217;ve learned.</p>
<p><span id="more-850"></span></p>
<p>A transform is a filter that can be applied to step definition arguments to refactor out common code.  The simplest example is one in which you want to convert all number arguments to numbers instead of strings.  Actually this can be used for far more advanced transformations than just numeric transformations.  Let&#8217;s look at a few examples and rewrite some step definitions from previous postings at the same time.</p>
<h3>Looking back</h3>
<p>In a previous <a href="http://www.cheezyworld.com/2010/11/09/ui-tests-not-brittle/">article</a> we wrote cukes to verify the contents of a shopping cart.  We had  <i>Scenarios</i> that had steps like this:</p>
<pre><code>And I should see "Pragmatic Project Automation" in the description for line "1"
And I should see "29.95" in the each for line "1"
And I should see "29.95" in the total for line "1"</code></pre>
<p>and the corresponding step definitions:</p>
<p><code></p>
<pre class="brush:ruby">
Then /^I should see "([^\"]*)" in the description for line "([^\"]*)"$/ do |desc, line|
  @shopping_cart.description_for_line(line.to_i).should == desc
end

Then /^I should see "([^\"]*)" in the each for line "([^\"]*)"$/ do |each, line|
  @shopping_cart.each_for_line(line.to_i).should == "$#{each}"
end

Then /^I should see "([^\"]*)" in the total for line "([^\"]*)"$/ do |total, line|
  @shopping_cart.total_for_line(line.to_i).should == "$#{total}"
end
</pre>
<p></code></p>
<p>The first thing I would like to point out is that I am calling <code>to_i</code> on each line value passed into the step.  The second thing to notice is that I am transforming each book price to a dollar amount like <code>"$#{total}"</code>.  These are both candidates for using Transforms.</p>
<h3>Two transforms to go</h3>
<p>Let&#8217;s start by eliminating the need to convert the string line number to a number.  The common pattern here is that we are stating <code>line "1"</code> in each step.  Let&#8217;s create a Transform for this.</p>
<p><code></p>
<pre class="brush:ruby">
Transform /^line (\d+)$/ do |line_string|
  line_string.to_i
end
</pre>
<p></code></p>
<p>This transformation works by looking through the <i>Scenarios</i> and finding portions of steps that match <code>"line N"</code> where N is a number.  When it finds a match it calls our <code>Transform</code> and places the number string value into the <code>line_string</code> parameter.  The code in the step simply calls <code>to_i</code> on the string to convert it to a number.  Notice that we did not include the double quotes in the pattern to match.  With this simple Transformation we can eliminate all of the duplicate <code>to_i</code> calls in our steps.  We can also eliminate the need for the double quotes around the number.</p>
<p><code></p>
<pre class="brush:ruby">
Then /^I should see "([^\"]*)" in the description for (line \d+)$/ do |desc, line|
  @shopping_cart.description_for_line(line).should == desc
end
</pre>
<p></code></p>
<p>Notice how our pattern in the step definition is <code>(line \d+)</code>.  We are creating the pattern that will match our Transform.  We also need to modify the <i>Scenario</i> to remove the double quotes.</p>
<pre><code>And I should see "Pragmatic Project Automation" in the description for line 1</code></pre>
<p>Very good!</p>
<p>Now let&#8217;s move on to the dollar transformation.  We need to create a transformation for any number of digits, a period, and exactly two digits.  Here is what that looks like.</p>
<p><code></p>
<pre class="brush:ruby">
Transform /^(\d+\.\d{2})$/ do |dollar_amount|
  "$#{dollar_amount}"
end
</pre>
<p></code></p>
<p>And with this transformation we can now remove all of the string formatting in our step definitions.</p>
<p><code></p>
<pre class="brush:ruby">
Then /^I should see "([^\"]*)" in the each for line "([^\"]*)"$/ do |each, line|
  @shopping_cart.each_for_line(line.to_i).should == each
end

Then /^I should see "([^\"]*)" in the total for line "([^\"]*)"$/ do |total, line|
  @shopping_cart.total_for_line(line.to_i).should == total
end
</pre>
<p></code></p>
<p>That&#8217;s all there is to it.  By creating these simple transformations I was able to eliminate duplication I had in several step definitions.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cheezyworld.com/2011/02/20/transforming-my-cukes/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using the database in our tests</title>
		<link>http://www.cheezyworld.com/2011/02/13/using-the-database-in-our-tests/</link>
		<comments>http://www.cheezyworld.com/2011/02/13/using-the-database-in-our-tests/#comments</comments>
		<pubDate>Sun, 13 Feb 2011 21:18:12 +0000</pubDate>
		<dc:creator>cheezy</dc:creator>
				<category><![CDATA[Book]]></category>
		<category><![CDATA[Cucumber]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.cheezyworld.com/?p=830</guid>
		<description><![CDATA[I&#8217;m releasing another chapter of my book. It is the chapter we focus on using a database in our tests. The chapter uses ActiveRecord and several additional gems. Please give it a read and let me know what you think. &#8230; <a href="http://www.cheezyworld.com/2011/02/13/using-the-database-in-our-tests/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m releasing another chapter of my book.  It is the chapter we focus on using a database in our tests.  The chapter uses <i>ActiveRecord</i> and several additional gems.  Please give it a read and let me know what you think.</p>
<p><span id="more-830"></span></p>
<table>
<tr>
<td>Chapter 3: Getting our feet wet with Watir</td>
<td><a href='http://www.cheezyworld.com/wp-content/uploads/2011/02/Chapter3.pdf'>PDF</a></td>
<td><a href='http://www.cheezyworld.com/wp-content/uploads/2011/02/Chapter3.epub'>ePub</a></td>
<td><a href='http://www.cheezyworld.com/wp-content/uploads/2011/02/Chapter3.mobi'>Kindle</a></td>
</tr>
<tr>
<td>Chapter 4: Getting started with Cucumber</td>
<td><a href='http://www.cheezyworld.com/wp-content/uploads/2011/02/Chapter4.pdf'>PDF</a></td>
<td><a href='http://www.cheezyworld.com/wp-content/uploads/2011/02/Chapter4.epub'>ePub</a></td>
<td><a href='http://www.cheezyworld.com/wp-content/uploads/2011/02/Chapter4.mobi'>Kindle</a></td>
</tr>
<tr>
<td>Chapter 5: Using a database in our tests</td>
<td><a href='http://www.cheezyworld.com/wp-content/uploads/2011/02/Chapter5.pdf'>PDF</a></td>
<td><a href='http://www.cheezyworld.com/wp-content/uploads/2011/02/Chapter5.epub'>ePub</a></td>
<td><a href='http://www.cheezyworld.com/wp-content/uploads/2011/02/Chapter5.mobi'>Kindle</a></td>
</tr>
</table>
<p>If you&#8217;re interested in what&#8217;s coming up, I plan to release another chapter next week that parses and creates XML in our tests.  After that I will release a new version of these chapters using a new example application.  After that&#8230;</p>
<h3>Outline</h3>
<p>I&#8217;ve had several people ask me for a full outline for my book.  Here are the chapter titles and brief description.  This is all subject to change of course.</p>
<p><b>1. Introducing Acceptance Testing</b>:   This chapter will begin with a discussion on what is wrong with the way we typically test software today.  It will point out the waste/rework caused by testing software after development and duplication caused by writing detailed test plans.  It will then turn the focus on acceptance test driven development and demonstrate the efficiencies gained by adopting this practice.  It will conclude with a description of how acceptance test driven development effects the entire process of delivering high quality software.</p>
<p><b>2. Installing the software</b>:   This chapter takes the reader through the process of installing Ruby, cucumber and a few additional gems, and an evaluation copy of RubyMine.  Through the book I demonstrate how to do the activities through both the command-line and RubyMine.</p>
<p><b>3. Getting our feet wet with Watir</b>:   Watir is the foundation of my web testing strategy.  In this chapter I introduce the reader to some basic Ruby concepts as well as taking them through the process of writing a few simple scripts using Watir.  Along the way we also introduce a few design concepts to help us keep our code clean and maintainable.  This is one of the two sample chapters I am including in this proposal</p>
<p><b>4. Getting started with Cucumber </b>:  We finally introduce the reader to cucumber.  We also introduce more Ruby concepts including classes.  After writing a few basic scenarios and scenario outlines we turn our focus to writing more robust scenarios with page objects and default data.  We conclude the chapter by discussing what level of granularity to use when writing scenarios.</p>
<p><b>5. Using a database in our tests</b>:   Frequently we need to stage or read data for out tests.  In this chapter we introduce ActiveRecord as well as a few additional gems (factory_girl and pickle) to make this task easier.  We do this by writing a couple of Scenarios against the database for our example web application and then enhance it by adding additional gems and techniques.  We also demonstrate how our default data pattern from the previous chapter is applicable to this testing area.</p>
<p><b>6. Testing XML</b>:   Producing or validating XML is a common task for testers.  This chapter introduces a couple of gems to help with this task.  We end the chapter by creating scenarios that can create an XML contact list and then other scenarios that can verify the content of that list.</p>
<p><b>7. At your service</b>:   Service oriented architectures are still very popular.  In this chapter we write a feature that specifies a web service that stock quotes.  The scenarios will test both a restful and soap version of this service.</p>
<p><b>8. Ready for Web 2.0 </b>:  Testing applications that have a lot of javascript and ajax calls introduces a new set of challenges.  We tackle these challenges head on by writing scenarios against an ajax version of our example web application.  We finish the chapter by writing an extension to the Watir gem that allows us to test drag-and-drop.</p>
<p><b>9. Going Mobile</b>:   Most people still manually test their mobile applications.  In this chapter we introduce iCuke to test an iPhone application.  We also demonstrate how the page object and default data patterns apply to this type of testing.</p>
<p><b>10. Hanging out with the natives</b>:   Sometimes our tests need to make calls into libraries written in compiled languages.  This chapter will begin writing scenarios to test the functionality of a library written in C.  We will then proceed by using the gem ffi to create a wrapper around the library to enable us to make direct calls.  Next we will write a higher level domain specific language to make our calls simpler.  We will finish by using the DSL in our step definitions to complete the tests.</p>
<p><b>11. I’ve lost my head</b>:   In this chapter we will write the Scenarios for an application that reads data from a set of tables, performs some data transformation, and then writes the data into another set of tables.  A secondary focus will be on how do you test an application when you can’t see it run.  We will also build upon some of the design patterns we introduced in previous chapters.</p>
<p><b>12. Mocking processes</b>:   What do you do when the software you are testing needs to talk to hardware?  What do you do when you application talks to a web service that doesn’t exist yet?  This chapter focuses on creating surrogates for volatile or missing components in order to facilitate testing now.</p>
<p><b>Appendix A</b>:  Watir Quick Reference</p>
<p><b>Appendix B</b>:  RSpec Matcher Quick Reference</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cheezyworld.com/2011/02/13/using-the-database-in-our-tests/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>My Book</title>
		<link>http://www.cheezyworld.com/2011/02/02/my-book/</link>
		<comments>http://www.cheezyworld.com/2011/02/02/my-book/#comments</comments>
		<pubDate>Thu, 03 Feb 2011 03:15:50 +0000</pubDate>
		<dc:creator>cheezy</dc:creator>
				<category><![CDATA[Book]]></category>
		<category><![CDATA[Cucumber]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.cheezyworld.com/?p=796</guid>
		<description><![CDATA[For the past two of years I have had a string of successes and a lot of fun helping teams adopt Acceptance Test Driven Development with Cucumber. I was never brought in to do this specifically. You see, I am &#8230; <a href="http://www.cheezyworld.com/2011/02/02/my-book/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>For the past two of years I have had a string of successes and a lot of fun helping teams adopt Acceptance Test Driven Development with Cucumber.  I was never brought in to do this specifically.  You see, I am an agile coach and I help team adopt agile and lean practices.  And yet due to these successes with Cucumber I started thinking about how I might share these experiences.</p>
<p>I initially decided I would write a blog series.  When I outlined it I quickly determined it would take nearly thirty entries to share all I wanted to share.  That was when I came up with the crazy idea of writing a book.  I had no idea what I was getting myself into.  For the past several months I have spent a fair amount of my free time (do I really have free time?) working on this book.  With this post I am releasing the first two chapters of that book.</p>
<p><span id="more-796"></span></p>
<p>The book is primarily written for testers with little or no scripting experience.  In the book I am introducing the reader to Acceptance Testing, Ruby, Cucumber, and good design principles.  Perhaps that is too much to ask for one book but I&#8217;ll let you be the judge.</p>
<p>The two chapters below will need a fair amount of rework.  You see, I made a mistake.  When I got started with this endeavor the words started flowing rapidly.  I really needed a simple application I could use to write my tests against.  An application quickly came to mind and I downloaded it and started to use it in my writings.  A few months and several chapters later I decided to check to make sure I really had the &#8220;rights&#8221; to use this example.  I didn&#8217;t.</p>
<p>I am in the process of completing a new example application and once it is finished I will be changing these chapters (and others) to use it.</p>
<h3>What&#8217;s covered?</h3>
<p>The book talks about techniques and patterns that can be used to tests many different types of applications.  There are a few chapters on testing web applications but there are also chapters on testing mobile applications, native win32 applications, web services, as well as headless applications.  We also have chapters that cover reading and writing XML and using databases in your tests.</p>
<h3>When will the book be released?</h3>
<p>I have most of the book written although I will have to rewrite a few chapters once I finish the new example application.  The main item that remains is finding a publisher (if you&#8217;re out there please give me a call!).  Overall I hope the book will be out by the summer.</p>
<h3>Show me the book please!</h3>
<p>I am including chapters three and four.  I welcome all feedback!</p>
<table>
<tr>
<td>Chapter 3</td>
<td><a href='http://www.cheezyworld.com/wp-content/uploads/2011/02/Chapter3.pdf'>PDF</a></td>
<td><a href='http://www.cheezyworld.com/wp-content/uploads/2011/02/Chapter3.epub'>ePub</a></td>
<td><a href='http://www.cheezyworld.com/wp-content/uploads/2011/02/Chapter3.mobi'>Kindle</a></td>
</tr>
<tr>
<td>Chapter 4</td>
<td><a href='http://www.cheezyworld.com/wp-content/uploads/2011/02/Chapter4.pdf'>PDF</a></td>
<td><a href='http://www.cheezyworld.com/wp-content/uploads/2011/02/Chapter4.epub'>ePub</a></td>
<td><a href='http://www.cheezyworld.com/wp-content/uploads/2011/02/Chapter4.mobi'>Kindle</a></td>
</tr>
</table>
]]></content:encoded>
			<wfw:commentRss>http://www.cheezyworld.com/2011/02/02/my-book/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Bowling Game in C++</title>
		<link>http://www.cheezyworld.com/2011/01/12/bowling-game-in-c/</link>
		<comments>http://www.cheezyworld.com/2011/01/12/bowling-game-in-c/#comments</comments>
		<pubDate>Wed, 12 Jan 2011 14:12:06 +0000</pubDate>
		<dc:creator>cheezy</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Test Driven Development]]></category>

		<guid isPermaLink="false">http://www.cheezyworld.com/?p=774</guid>
		<description><![CDATA[Last year was a blast. I started the year coaching a team that was developing a grails web application. Next was a batch application written in perl and pl-sql. Next I moved on to objective-c and then on to php &#8230; <a href="http://www.cheezyworld.com/2011/01/12/bowling-game-in-c/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Last year was a blast.  I started the year coaching a team that was developing a <b>grails</b> web application.  Next was a batch application written in <b>perl</b> and <b>pl-sql</b>.  Next I moved on to <b>objective-c</b> and then on to <b>php</b> and <b>flash</b>.  I finished the year in <b>java</b>.  I used <b>ruby</b> for testing with all of the teams.  The variety has been fantastic and I have enjoyed each assignment.  One thing that was really encouraging was that I found good unit testing framework in each language.</p>
<p>Last Thursday I attended the <a href="http://www.meetup.com/ClevelandRuby/" target="_blank">Cleveland Ruby Brigade</a> meeting.  It was nice to see a some old friends.  I mentioned a few times that I had just started working with a team that was using C++.  Each time the reaction was negative.  People said things like &#8220;I&#8217;m sorry for you&#8221;.  Actually, there is nothing to be sorry about.  C++ is a strong language that has continued to evolve over the years and will have a place in software development for the foreseeable future.</p>
<p>The negative reaction to C++ encouraged me to create this screencast (my first ever).  I had some time Monday morning before work so I turned on the recorder.  I am using <a href="http://code.google.com/p/googletest/" target="_blank">Google Test</a> to drive the design.  I hope you enjoy.</p>
<p><iframe src="http://player.vimeo.com/video/18702263" width="640" height="360" frameborder="0"></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cheezyworld.com/2011/01/12/bowling-game-in-c/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

