Hi Jonathan.<br><br>You can think of the What&#39;s in a Story article as trainer wheels. The point is to start thinking in givens, events and outcomes (ie. which activities in this scenario are setting up context, which are the &quot;interesting bits&quot; and which are verification).
<br><br>Once you are comfortable with this, it is perfectly natural to want multiple steps interleaved. A very common pattern is to have some Givens then repeating sequences of Whens and Thens, which represent various operations through a user scenario. So you might say:
<br><br>Given I am on the login screen<br><br>When I enter my credentials<br>Then I should be on the summaries page<br><br>When I select an entry<br>Then I should see its detail<br><br>When I delete the entry<br>Then I should be back on the summary page
<br>And the deleted entry should have disappeared<br><br>As long as you are aware what each stanza represents (&quot;I should be back on the summary page&quot; is an outcome, &quot;I select an entry&quot; is an event, etc.) then you&#39;re definitely on the right lines.
<br><br>I just found a paragraph from the article that might help:<br><br><div style="margin-left: 40px;">&quot;Not all scenarios are this simple. Some are best represented as a sequence of events, described as: <em>given [some context] when [I do something] then [this happens] when [I do another thing] then [this new thing happens]
</em>
and so on. An example is a wizard-style website, where you step through
a sequence of screens to build up a complex data model. It is perfectly
appropriate to intermingle sequences of events and outcomes, as long as
you get into the habit of thinking in these terms.&quot;<br></div><br>Thanks,<br>Dan<br><br><br><div><span class="gmail_quote">On 10/3/07, <b class="gmail_sendername">Jonathan Linowes</b> &lt;<a href="mailto:jonathan@parkerhill.com">
jonathan@parkerhill.com</a>&gt; wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">Pat,<br><br>Any more thoughts on submit_form and follow_link? I really like that
<br>idea, it fits well with the story concept, imo . And using the links<br>and forms inside the response is better coverage than assuming the<br>entry point to the next page.<br><br>So a scenario becomes a sequence of actions taken by the user to
<br>accomplish a task (however small or large).<br>In which case, could you have multiple When-Then&#39;s ? eg from your<br>example<br><br><br>&gt;&nbsp;&nbsp; Scenario &quot;Successful listing&quot; do<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; Given &quot;A user&quot; do
<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; User.create! :login =&gt; &quot;pat&quot;, :password =&gt; &quot;password&quot;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; end<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; When &quot;user visits the login page&quot; do<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get &quot;/login&quot;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; end
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Then &quot;user sees login page&quot; do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; response.should have_text(/Please login/)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; When &quot;user logs in&quot; do<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; submit_form :login, :login =&gt; &quot;pat&quot;, :password =&gt; &quot;password&quot;
<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; end<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Then &quot;page shows Create an auction&quot; do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; response.should have_tag(...)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; When &quot;user visits new auction page&quot; do<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; click_link &quot;Create an auction&quot;
<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; end<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; When &quot;user creates auction&quot; do<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; submit_form :auction, :auction =&gt; { :item_name =&gt; &quot;Ruby for<br>&gt; Rails&quot;, :price =&gt; 50 }<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; end<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; Then &quot;new auction should be listed&quot; do
<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; response.should have_text(/Item successfully created!/)<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; response.should have_text(/Ruby for Rails/)<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; end<br>&gt;&nbsp;&nbsp; end<br><br><br>I realize this goes against <a href="http://dannorth.net/whats-in-a-story">
http://dannorth.net/whats-in-a-story</a> but<br>it seems more correct than putting those actions into Given clauses.<br><br><br>On Sep 25, 2007, at 6:48 PM, Pat Maddox wrote:<br><br>&gt; On 9/25/07, David Chelimsky &lt;<a href="mailto:dchelimsky@gmail.com">
dchelimsky@gmail.com</a>&gt; wrote:<br>&gt;&gt; On 9/25/07, Jonathan Linowes &lt;<a href="mailto:jonathan@parkerhill.com">jonathan@parkerhill.com</a>&gt; wrote:<br>&gt;&gt;&gt; hi,<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; I just started fooling around with story runner, thought I&#39;d start
<br>&gt;&gt;&gt; with a dead simple scenario:<br>&gt;&gt;&gt; The first thing I do when describing a site to someone is go to the<br>&gt;&gt;&gt; home page, and begin exploring public pages from there.<br>&gt;&gt;&gt; So, that seems like a good first story to spec out.
<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; And I&#39;d really like to extract the actual link from the rendered<br>&gt;&gt;&gt; page<br>&gt;&gt;&gt; (rather than just &quot;assuming&quot; in the spec), but I&#39;m not sure how<br>&gt;&gt;&gt; to do
<br>&gt;&gt;&gt; that<br>&gt;&gt;&gt; Something like:<br>&gt;&gt;&gt;<br>&gt;&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# alink = find tag &#39;div#home-banner-links a &#39;&nbsp;&nbsp;where<br>&gt;&gt;&gt; content==&quot;About&quot;<br>&gt;&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# url = extract the href attribute from alink
<br>&gt;&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;get url<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; Here&#39;s the story so far: <a href="http://pastie.caboo.se/100810">http://pastie.caboo.se/100810</a><br>&gt;&gt;<br>&gt;&gt; Some comments:<br>&gt;&gt;<br>
&gt;&gt; The second scenario seems more like the right level of abstraction<br>&gt;&gt; than the first. Using &quot;should render_template&quot; in a Story seems too<br>&gt;&gt; low level to me. What&#39;s interesting is what is being displayed, not
<br>&gt;&gt; what template is being used to display it.<br>&gt;<br>&gt; I see what you&#39;re getting at.&nbsp;&nbsp;I&#39;ve thought about it a bit myself, and<br>&gt; have decided that expecting a certain template is a pragmatic way of
<br>&gt; knowing that the user is on the right page.<br>&gt;<br>&gt;<br>&gt;&gt; The second scenario does a nicer job of that.<br>&gt;&gt;<br>&gt;&gt; One thing is that you won&#39;t be able to use the full URL. RailsStory
<br>&gt;&gt; wraps rails integration tests, which provide access to routing,<br>&gt;&gt; but as<br>&gt;&gt; paths, not URLs. So for href=&quot;<a href="http://0.0.0.0:3000/site_pages/about">http://0.0.0.0:3000/site_pages/about
</a>&quot;,<br>&gt;&gt; you&#39;d need to extract the &quot;/site_pages/about&quot; part and get that.<br>&gt;&gt;<br>&gt;&gt; Thoughts?<br>&gt;<br>&gt; I was planning on implementing a<br>&gt; click_link &quot;Follow me!&quot;
<br>&gt;<br>&gt; sorta thing in the next couple days.&nbsp;&nbsp;One problem I have is that right<br>&gt; now you still need to know too much about the underlying structure<br>&gt; (and golly if I didn&#39;t just contradict the first part of my reply!).
<br>&gt; There was a thread a few days ago [1] where I hinted at that.&nbsp;&nbsp;He<br>&gt; wanted to go directly to a URL, when he should have been following a<br>&gt; redirect.<br>&gt;<br>&gt; I think there needs to be some mechanism for following links /
<br>&gt; submitting forms so that you can really follow the path a user takes.<br>&gt; That leaves you with something like:<br>&gt;<br>&gt; Story &quot;Create an auction&quot;, %{<br>&gt;&nbsp;&nbsp; As a seller<br>&gt;&nbsp;&nbsp; I want to create a new auction
<br>&gt;&nbsp;&nbsp; So that I can get filthy rich<br>&gt; } do<br>&gt;<br>&gt;&nbsp;&nbsp; Scenario &quot;Successful listing&quot; do<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; Given &quot;A user&quot; do<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; User.create! :login =&gt; &quot;pat&quot;, :password =&gt; &quot;password&quot;
<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; end<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; And &quot;user visits the login page&quot; do<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get &quot;/login&quot;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; end<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; And &quot;user logs in&quot; do<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; submit_form :login, :login =&gt; &quot;pat&quot;, :password =&gt; &quot;password&quot;
<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; end<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; And &quot;user visits new auction page&quot; do<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; click_link &quot;Create an auction&quot;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; end<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; When &quot;user creates auction&quot; do<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; submit_form :auction, :auction =&gt; { :item_name =&gt; &quot;Ruby for
<br>&gt; Rails&quot;, :price =&gt; 50 }<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; end<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; Then &quot;new auction should be listed&quot; do<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; response.should have_text(/Item successfully created!/)<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; response.should have_text(/Ruby for Rails/)
<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; end<br>&gt;&nbsp;&nbsp; end<br>&gt; end<br>&gt;<br>&gt; That requires you to know<br>&gt; 1. Point of entry<br>&gt; 2. IDs of forms and links (or text for links, if you prefer)<br>&gt; 3. The fields that a form uses<br>
&gt;<br>&gt; So really all we&#39;ve gotten away from is dependency on knowing certain<br>&gt; URLs, which I&#39;m not positive is a huge benefit...otoh, this is closer<br>&gt; to tracing a user&#39;s path through the app which is nice.
<br>&gt;<br>&gt; wdyt?<br>&gt;<br>&gt; Pat<br>&gt;<br>&gt; [1] <a href="http://rubyforge.org/pipermail/rspec-users/2007-September/">http://rubyforge.org/pipermail/rspec-users/2007-September/</a><br>&gt; 003344.html<br>&gt; _______________________________________________
<br>&gt; rspec-users mailing list<br>&gt; <a href="mailto:rspec-users@rubyforge.org">rspec-users@rubyforge.org</a><br>&gt; <a href="http://rubyforge.org/mailman/listinfo/rspec-users">http://rubyforge.org/mailman/listinfo/rspec-users
</a><br><br>_______________________________________________<br>rspec-users mailing list<br><a href="mailto:rspec-users@rubyforge.org">rspec-users@rubyforge.org</a><br><a href="http://rubyforge.org/mailman/listinfo/rspec-users">
http://rubyforge.org/mailman/listinfo/rspec-users</a><br></blockquote></div><br>