cucumber-in-the-yard 1.7.2 → 1.7.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. data/History.txt +12 -0
  2. data/README.md +22 -0
  3. data/example/child_feature/child.feature +11 -0
  4. data/example/child_feature/grandchild_feature/grandchild.feature +12 -0
  5. data/example/scenario.feature +23 -13
  6. data/example/scenario_outline.feature +26 -6
  7. data/lib/city.rb +1 -1
  8. data/lib/cucumber/city_builder.rb +2 -2
  9. data/lib/templates/default/feature/html/feature.erb +24 -18
  10. data/lib/templates/default/feature/html/outline.erb +21 -6
  11. data/lib/templates/default/feature/html/pystring.erb +1 -1
  12. data/lib/templates/default/feature/html/scenario.erb +3 -2
  13. data/lib/templates/default/feature/html/steps.erb +1 -1
  14. data/lib/templates/default/feature/setup.rb +4 -0
  15. data/lib/templates/default/featuredirectory/html/setup.rb +1 -0
  16. data/lib/templates/default/featuretags/html/namespace.erb +68 -34
  17. data/lib/templates/default/featuretags/html/setup.rb +4 -3
  18. data/lib/templates/default/fulldoc/html/css/common.css +40 -25
  19. data/lib/templates/default/fulldoc/html/full_list.erb +2 -0
  20. data/lib/templates/default/fulldoc/html/js/cucumber.js +60 -32
  21. data/lib/templates/default/fulldoc/html/setup.rb +1 -1
  22. data/lib/templates/default/requirements/html/setup.rb +3 -0
  23. data/lib/templates/default/steptransformers/html/header.erb +5 -5
  24. data/lib/templates/default/steptransformers/html/transformers.erb +55 -49
  25. data/lib/templates/default/steptransformers/html/undefined_steps.erb +12 -6
  26. data/lib/templates/default/steptransformers/setup.rb +6 -0
  27. data/lib/yard/code_objects/cucumber/feature.rb +2 -2
  28. data/lib/yard/code_objects/cucumber/scenario_outline.rb +6 -1
  29. metadata +16 -10
  30. data/example/child_feature/grandchild_feature/scenario.feature +0 -52
  31. data/example/child_feature/scenario.feature +0 -57
@@ -21,13 +21,14 @@ def tags
21
21
  end
22
22
 
23
23
  def features
24
- @features ||= Registry.all(:feature).sort {|x,y| x.value <=> y.value }
24
+ @features ||= Registry.all(:feature).sort {|x,y| x.value.to_s <=> y.value.to_s }
25
25
  end
26
26
 
27
- def scenarios
28
- @scenarios ||= features.collect {|f| f.scenarios.reject {|s| s.background? } }.flatten.sort {|x,y| x.value <=> y.value }
27
+ def feature_tags_with_all_scenario_tags(feature)
28
+ feature.tags.collect {|t| t.value} + feature.scenarios.collect {|s| s.tags.collect {|t| t.value} }.flatten.uniq
29
29
  end
30
30
 
31
+
31
32
  def tagify(tag)
32
33
  %{<span class="tag" href="#{url_for tag}">#{tag.value}</span>}
33
34
  end
@@ -4,10 +4,12 @@
4
4
  .tags { font-family: monospace; font-size: 14px; }
5
5
  .title { padding: 10px; font-size: 24px; }
6
6
 
7
- #view, #expand { float: right; font-size: 13px; color: gray; vertical-align: bottom; }
8
- .control { float: right; font-size: 13px; color: gray; vertical-align: bottom; font-family: monospace; font-size: 14px; cursor: pointer; }
7
+ .control { float: right; font-size: 13px; color: #05A; vertical-align: bottom; font-family: monospace; font-size: 14px; cursor: pointer; }
8
+
9
+ .title { margin: 20px 20px 10px 20px; padding-left: 0px; border-bottom: 1px solid #E3E3E3; }
10
+ .noborder { border: none; }
11
+ #header * .title { padding: 10px; margin: 0px; border: none; }
9
12
 
10
- .title { margin: 20px 20px 10px 20px; padding-left: 0px; border-bottom: 1px solid #E3E3E3; }
11
13
  .meta .file { float: right; margin-top: 5px; margin-right: 20px; }
12
14
  .title .pre { color: #696969; }
13
15
  .title .name { font-weight: bold; color: #3F3F3F; }
@@ -16,11 +18,14 @@
16
18
  .scenario .meta .tags { margin-left: 0px; }
17
19
  .feature .meta .tags { float: right; margin-right: 20px; }
18
20
 
21
+ .suggestion { color: #ff686e; }
22
+
19
23
 
20
24
  .feature .description, .requirements .summary {
21
25
  margin: 10px 20px 0px 30px;
22
26
  padding: 10px 20px 20px 10px;
23
27
  color: #343332;
28
+ font-size: 16px;
24
29
  font-family: 'Trebuchet MS', Arial, Helvetica;
25
30
  }
26
31
 
@@ -44,6 +49,10 @@
44
49
  padding: 6px 10px; margin-top: 18px;
45
50
  background: #e5e8ff; border: 1px solid #d8d8e5; -moz-border-radius: 3px; -webkit-border-radius: 3px;
46
51
  }
52
+ .nodefinitions .title {
53
+ background-color: #F5EADD; border: 1px solid #d8d8e5; -moz-border-radius: 3px; -webkit-border-radius: 3px;
54
+ }
55
+
47
56
  .scenario .title { border: none; }
48
57
  .background .title { background: #cbddeb; }
49
58
 
@@ -86,11 +95,11 @@
86
95
 
87
96
  .comments { margin-left: 25px; color: gray; padding: 5px; font-size: 13px; }
88
97
  .scenario .steps .comments { margin-left: 0px; }
89
-
98
+ .feature .comments { margin-left: 30px; padding: 10px 20px 20px 10px; }
90
99
 
91
100
  .step .predicate { color: #5D5C5B; }
92
-
93
101
  .step .defined {}
102
+ div.undefined { padding: 6px; }
94
103
  .step .definition { float: right; color: #343332; }
95
104
  .step .details .pre {}
96
105
  .step .details .name { font-family: monospace; color: black; }
@@ -104,6 +113,7 @@
104
113
  border: 1px solid #DEDEDE;
105
114
  }
106
115
 
116
+ /* Scenario Outline Table */
107
117
  .outline {
108
118
  margin-top: 20px;
109
119
  margin-left: 40px;
@@ -114,7 +124,6 @@
114
124
  font-size: 16px;
115
125
  }
116
126
 
117
-
118
127
  .multiline table tr, .outline table tr {
119
128
  padding: 4px;
120
129
  }
@@ -128,7 +137,8 @@
128
137
  padding: 4px 10px 4px 10px;
129
138
  }
130
139
 
131
- /* tag page */
140
+
141
+ /* Tag page */
132
142
  #tags #features, #tags #scenarios { margin-right: 20px;}
133
143
  #tags * .tag { font-family: monospace; font-size: 14px; cursor: pointer; }
134
144
 
@@ -137,39 +147,46 @@
137
147
  .tag .scenario { margin-top: 0px; margin-left: 20px; padding-left: 30px; }
138
148
  .tag .scenario .title { border-bottom: none; }
139
149
  .tag .scenario .meta { margin-top: 0px; }
140
- /* Overrides for scenarios in the tag view */
141
-
142
150
 
143
151
 
152
+ /* Step Transformer Page */
153
+ .transformer { margin-top: 20px; }
144
154
  .transformer * .docstring { margin-left: 20px; margin-top: 10px; padding: 5px 5px 5px 10px; }
145
- .transformer .steps, .method_details_list, .steps, .method_details_list {
146
- margin: 10px 20px 0px 30px;
147
- }
148
- .transformer .steps .step { padding: 4px; }
149
-
155
+ .transformer .steps, .method_details_list, .steps, .method_details_list { margin: 10px 20px 0px 30px; }
156
+ .transformer .steps .step { padding: 6px; font-size: 14px; }
150
157
 
151
158
 
159
+ /* Tag Search Page */
152
160
  #tags * li { padding: 5px; padding-left: 12px; margin: 0 0 0 10px; font-size: 1.1em; list-style: none; }
153
-
154
161
  #tag_search { margin: 10px 0px 10px 0px; width: 100%; min-width: 200px; height: 20px; }
155
162
  #tag_filtering {
156
- margin: 10px 20px 0px 40px;
163
+ margin: 10px 20px 0px 30px;
157
164
  font-weight: bold;
158
165
  padding: 20px;
159
166
  background-color: #F8F8FF;
160
167
  color: #444444;
161
- border: 1px solid #DEDEDE;
168
+ border: 1px solid #DEDEDE; -moz-border-radius: 3px; -webkit-border-radius: 3px;
162
169
  }
163
- #command_example { margin-top: 10px; margin-left: 10px; font-weight: normal; }
164
170
 
171
+ #command_example {
172
+ margin-top: 10px;
173
+ margin-left: 0px;
174
+ font-size: 1.1em; font-weight: normal; font-family: Monaco, Consolas, Courier, monospace;
175
+ color: #333;
176
+ padding: 8px 10px;
177
+ background: #A8E795; border: 1px solid #d8d8e5; -moz-border-radius: 3px; -webkit-border-radius: 3px;
178
+ }
165
179
 
166
180
 
167
- #cukes_links { margin: 10px auto 10px auto;
168
- border-bottom: 1px solid #E3E3E3;
169
- width: 762px; text-align: center;
170
- padding: 10px;
181
+ #cukes_links {
182
+ margin: 10px auto 10px auto;
183
+ border-bottom: 1px solid #E3E3E3;
184
+ width: 762px; text-align: center;
185
+ padding: 10px;
171
186
  }
172
187
 
188
+ /* Logo Image and Step Status Images */
189
+
173
190
  #cukes_logo {
174
191
  margin: 0px auto 10px auto;
175
192
  width: 762px;
@@ -188,6 +205,4 @@
188
205
  width: 15px;
189
206
  height: 15px;
190
207
  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAIAAAC0tAIdAAAACXBIWXMAAA86AAAPOgGXOdvCAAABWUlEQVQoFS2SvVEEMQyFJdkspFcCVAAVUREZXVAHHRAwZOQwQ3YM67X4nnwe3+3afn+S18/P9366s5yZ042R6c3c3bRKDw+WwZxf791Pt/3hMcev5QBpFtauPLoBYrYr6zcem/Xr8frUbc4c59zPPoekQeSesTm47IaD74kfTjnDbNqxC5pTzrJfQcCFBQClIh7bIdDc9S+6E8WIQXTl9somfA1S4iJVbUnJmyOhJT+51AMRkXVArMtBdUNLGcpmaReDdSIGHw4m2iyNIiMslTWqBvMuZSVZB4QhMRRp6IUjzYuPctvq3TpWumq2sIfNw/KQ3DwomfIv6aVBT+ZQMFKxhB8uLfhlzkO3Sstlwh1ja3+oEKVuqipGHhMztEGvvlZEQHwyMKPD1NDtrrpBR3jbalv90hWzo05FBr1vlKGXtvGF9fz5HG8vFRpK1a5yV0/KVuZSzO+Pf3G6tVs/+L00AAAAAElFTkSuQmCC) no-repeat center;
191
- }
192
-
193
- .conflicted {}
208
+ }
@@ -19,6 +19,8 @@
19
19
  <div id="content">
20
20
  <h1 id="full_list_header"><%= @list_title %></h1>
21
21
  <div id="nav">
22
+ <a target="_self" href="feature_list.html">Features</a> |
23
+ <a target="_self" href="tag_list.html">Tags</a> |
22
24
  <a target="_self" href="class_list.html">Classes</a> |
23
25
  <a target="_self" href="method_list.html">Methods</a> |
24
26
  <a target="_self" href="file_list.html">Files</a>
@@ -7,7 +7,22 @@ function cucumberSearchFrameLinks() {
7
7
  });
8
8
  }
9
9
 
10
+ function cucumberKeyboardShortcuts() {
11
+ if (window.top.frames.main) return;
12
+ $(document).keypress(function(evt) {
13
+ if (evt.altKey || evt.ctrlKey || evt.metaKey || evt.shiftKey) return;
14
+ if (typeof evt.orignalTarget !== "undefined" &&
15
+ (evt.originalTarget.nodeName == "INPUT" ||
16
+ evt.originalTarget.nodeName == "TEXTAREA")) return;
17
+ switch (evt.charCode) {
18
+ case 82: case 114: $('#features_list_link').click(); break; // 'r'
19
+ case 84: case 116: $('#tags_list_link').click(); break; // 't'
20
+ }
21
+ });
22
+ }
23
+
10
24
  $(cucumberSearchFrameLinks);
25
+ $(cucumberKeyboardShortcuts);
11
26
 
12
27
 
13
28
  $(function() {
@@ -92,6 +107,11 @@ $(function() {
92
107
 
93
108
  if (typeof eventObject.currentTarget !== "undefined") {
94
109
  var exampleRow = $(eventObject.currentTarget);
110
+
111
+ if (eventObject.currentTarget.className.match(/example\d+/) == null) {
112
+ return false;
113
+ }
114
+
95
115
  var exampleClass = eventObject.currentTarget.className.match(/example\d+/)[0];
96
116
  var example = exampleRow.closest('div.details').find('.' + exampleClass);
97
117
 
@@ -151,21 +171,24 @@ function updateTagFiltering(tagString) {
151
171
  var formulaTags = determineTagsUsedInFormula(tagString);
152
172
  displayExampleCommandLine(formulaTags);
153
173
  displayQualifyingFeaturesAndScenarios(formulaTags);
154
- hideEmptySections();
155
174
  fixSectionRowAlternations();
156
175
  }
157
176
 
177
+ function clearTagFiltering() {
178
+ updateTagFiltering("");
179
+ }
180
+
158
181
  function determineTagsUsedInFormula(tagString) {
159
182
 
160
183
  tagString = tagString.replace(/^(\s+)|(\s+)$/,'').replace(/\s{2,}/,' ');
161
184
 
162
- var tagGroup = tagString.match(/@\w+(,@\w+)*/g);
185
+ var tagGroup = tagString.match(/(?:~)?@\w+(,(?:~)?@\w+)*/g);
163
186
 
164
187
  var returnTags = [];
165
188
 
166
189
  if (tagGroup) {
167
190
  tagGroup.forEach(function(tag, index, array) {
168
- //console.log("Tag Group: " + tag);
191
+ console.log("Tag Group: " + tag);
169
192
  var validTags = removeInvalidTags(tag)
170
193
  if (validTags != "") {
171
194
  returnTags.push(validTags);
@@ -178,8 +201,11 @@ function determineTagsUsedInFormula(tagString) {
178
201
 
179
202
  function removeInvalidTags(tagGroup) {
180
203
  tagGroup.split(",").forEach(function(tag, index, array) {
204
+
205
+ baseTag = tag.match(/^~(.+)/) ? tag.match(/^~(.+)/)[1] : tag;
206
+
181
207
  //console.log("Validating Tag: " + tag)
182
- if (tag_list.indexOf(tag) === -1) {
208
+ if (tag_list.indexOf(baseTag) === -1) {
183
209
  //console.log("Removing Tag: " + tag);
184
210
  tagGroup = tagGroup.replace(new RegExp(',?' + tag + ',?'),"")
185
211
  }
@@ -197,28 +223,9 @@ function displayExampleCommandLine(tags) {
197
223
  }
198
224
  }
199
225
 
200
- function hideEmptySections() {
201
-
202
- ["feature","scenario"].forEach(function(section,index,sections) {
203
-
204
- if ( $("." + section + ":visible").length == 0 ) {
205
- $("#" + section + "s")[0].style.display = "none";
206
- } else {
207
- $("#" + section + "s")[0].style.display = "block";
208
- }
209
-
210
- });
211
- }
212
-
213
226
  function fixSectionRowAlternations() {
214
-
215
- ["feature","scenario"].forEach(function(section,index,sections) {
216
-
217
- $("." + section + ":visible")
218
- $("." + section + ":visible").each(function(index) {
219
- $(this).removeClass("r1 r2").addClass("r" + ((index % 2) + 1));
220
- });
221
-
227
+ $(".feature:visible,.scenario:visible").each(function(index){
228
+ $(this).removeClass("odd even").addClass( ((index + 1) % 2 == 0 ? "even" : "odd") );
222
229
  });
223
230
  }
224
231
 
@@ -227,20 +234,34 @@ function displayQualifyingFeaturesAndScenarios(tags) {
227
234
  if (tags.length > 0) {
228
235
 
229
236
  $(".feature,.scenario").each(function(feature){
230
- this.style.display = "none";
237
+ $(this).hide();
231
238
  });
232
239
 
233
240
  var tagSelectors = generateCssSelectorFromTags(tags);
234
241
 
235
242
  tagSelectors.forEach(function(selector,selectorIndex,selectorArray) {
236
- $(".feature." + selector.replace(/@/g,"\\@").replace(/\s/,".") + ",.scenario." + selector.replace(/@/g,"\\@").replace(/\s/,".")).each(function(matchItem) {
237
- this.style.display = "block";
243
+ var tags = selector;
244
+
245
+ $(".feature." + tags).each(function(index) {
246
+ $(this).show();
247
+ });
248
+ $(".scenario." + tags).each(function(index) {
249
+ $(this).show();
250
+ $(this).parent().prev().show();
238
251
  });
252
+
239
253
  });
254
+
255
+ if ( $(".feature:visible,.scenario:visible").length == 0 ) {
256
+ $("#features div.undefined").show();
257
+ } else {
258
+ $("#features div.undefined").hide();
259
+ }
260
+
240
261
 
241
262
  } else {
242
- $(".feature,.scenario").each(function(feature){
243
- this.style.display = "block";
263
+ $(".feature:hidden,.scenario:hidden").each(function(feature){
264
+ $(this).show();
244
265
  });
245
266
  }
246
267
 
@@ -255,8 +276,15 @@ function generateCssSelectorFromTags(tagGroups) {
255
276
 
256
277
  tagSelectors.forEach(function(selector,selectorIndex,selectorArray) {
257
278
  tagGroup.split(",").forEach(function(tag,tagIndex,tagArray) {
258
- //console.log("selector: " + (selector + " " + tag).trim());
259
- newTagSelectors.push((selector + " " + tag).trim());
279
+
280
+ if ( tag.match(/^~@.+$/) ) {
281
+ tag = tag.match(/^~(@.+)$/)[1]
282
+ //console.log("selector: " + (selector + " :not(" + tag + ")").trim());
283
+ newTagSelectors.push((selector + ":not(." + tag.replace(/@/g,"\\@") +")").trim());
284
+ } else {
285
+ //console.log("selector: " + (selector + " " + tag).trim());
286
+ newTagSelectors.push((selector + "." + tag.replace(/@/g,"\\@")).trim());
287
+ }
260
288
  });
261
289
 
262
290
  });
@@ -8,7 +8,7 @@ def init
8
8
 
9
9
  if @features
10
10
  @features.each {|feature| serialize(feature) }
11
- generate_full_list(@features)
11
+ generate_full_list @features.sort {|x,y| x.value.to_s <=> y.value.to_s }
12
12
  end
13
13
 
14
14
  @tags = Registry.all(:tag)
@@ -14,6 +14,7 @@ def all_features_by_letter
14
14
  objects = features
15
15
  objects = run_verifier(objects)
16
16
  objects.each {|o| (hash[o.value.to_s[0,1].upcase] ||= []) << o }
17
+ hash.values.each {|v| v.sort! {|a,b| b.value.to_s <=> a.value.to_s } }
17
18
  hash
18
19
  end
19
20
 
@@ -22,6 +23,7 @@ def all_scenarios_by_letter
22
23
  objects = scenarios
23
24
  objects = run_verifier(objects)
24
25
  objects.each {|o| (hash[o.value.to_s[0,1].upcase] ||= []) << o }
26
+ hash.values.each {|v| v.sort! {|a,b| b.value.to_s <=> a.value.to_s } }
25
27
  hash
26
28
  end
27
29
 
@@ -30,6 +32,7 @@ def all_directories_by_letter
30
32
  objects = feature_directories
31
33
  objects = run_verifier(objects)
32
34
  objects.each {|o| (hash[o.value.to_s[0,1].upcase] ||= []) << o }
35
+ hash.values.each {|v| v.sort! {|a,b| b.value.to_s <=> a.value.to_s } }
33
36
  hash
34
37
  end
35
38
 
@@ -1,9 +1,9 @@
1
1
  <div class="title">
2
- <div class="name"><%= @item_title %></div>
3
-
4
2
  <% if @item_type %>
5
- <div class="control" id="<%= @item_type.gsub(/\s/,'') %>">[Collapse All]</div>
6
- <div style="clear: right;"></div>
7
- <% end %>
3
+ <a class="control" href="#" id="<%= @item_type.gsub(/\s/,'') %>">[Collapse All]</a>
4
+ <div style="clear: right;"></div>
5
+ <% end %>
6
+
7
+ <div class="name"><%= @item_title %></div>
8
8
  </div>
9
9
 
@@ -1,61 +1,67 @@
1
1
  <% @items.each do |item| %>
2
2
 
3
- <div class="transformer <%= @item_type.gsub(/\s/,'') %>">
4
- <a name="<%= anchor_for item %>"></a>
5
- <div class="title">
6
- <span class="pre"><%= h item.keyword %></span>
7
- <span class="name"><%= h item.value %></span>
8
- <a style="float: right;" href="http://rubular.com/?regex=<%= urlencode item.value %>" target="_blank">Rubular</a>
9
- <div style="clear: both;"></div>
10
- </div>
3
+ <div class="transformer <%= @item_type.gsub(/\s/,'') %> <%= "nodefinitions" if item.steps.nil? || item.steps.empty? %>">
4
+ <a name="<%= anchor_for item %>"></a>
5
+ <div class="title">
6
+ <span class="pre"><%= h item.keyword %></span>
7
+ <span class="name"><%= h item.value %></span>
8
+ <a style="float: right;" href="http://rubular.com/?regex=<%= urlencode item.value %>" target="_blank">Rubular</a>
9
+ <div style="clear: both;"></div>
10
+ </div>
11
11
 
12
- <div class="details">
12
+ <div class="details">
13
13
 
14
- <div class="meta" style="clear: right;">
15
- <div class="file"><%= h item.location %></div>
16
- </div>
14
+ <!-- Comments -->
15
+ <div>
16
+ <%= T('docstring').run(options.dup.merge({:object => item})) %>
17
+ </div>
17
18
 
18
- <!-- Comments -->
19
- <div>
20
- <%= T('docstring').run(options.dup.merge({:object => item})) %>
21
- </div>
19
+ <div class="meta" style="clear: right;">
20
+ <div class="file"><%= h item.location %></div>
21
+ </div>
22
22
 
23
- <!-- Source Code -->
24
- <div class="method_details_list">
25
- <table class="source_code">
26
- <tr>
27
- <td>
28
- <pre class="lines"><%= "" %><%= h format_lines(item) %></pre>
29
- </td>
30
- <td>
31
- <pre class="code"><%= "" %><%= html_syntax_highlight item.source %></pre>
32
- </td>
33
- </tr>
34
- </table>
35
- </div>
23
+ <!-- Source Code -->
24
+ <div class="method_details_list">
25
+ <table class="source_code">
26
+ <tr>
27
+ <td>
28
+ <pre class="lines"><%= "" %><%= h format_lines(item) %></pre>
29
+ </td>
30
+ <td>
31
+ <pre class="code"><%= "" %><%= html_syntax_highlight item.source %></pre>
32
+ </td>
33
+ </tr>
34
+ </table>
35
+ </div>
36
36
 
37
- <!-- Matching Step Instances -->
38
- <div class="steps">
39
- <% if item.steps && !item.steps.empty? %>
40
- <% item.steps.each_with_index do |step,step_index| %>
41
- <div class="step <%= (step_index + 1) % 2 == 0 ? 'even' : 'odd' %>">
42
- <span class="predicate">
43
- <%= h step.keyword %>
44
- </span>
45
- <span class="defined">
46
- <%= link_transformed_step(step) %>
47
- </span>
48
- <a class="definition" href="<%= url_for step.scenario.feature %>"><%= h step.location %></a>
49
- <div style="clear: both;"></div>
50
- </div>
51
- <% end %>
52
- <% else %>
53
- <div class="undefined">No steps were found to match this <%= @item_type %>.</div>
54
- <% end%>
55
- </div>
37
+ <!-- Matching Step Instances -->
56
38
 
39
+ <div class="steps">
40
+ <% if item.steps && !item.steps.empty? %>
41
+ <% unique_steps(item.steps).each_with_index do |uniq_step,step_index| %>
42
+ <div class="step <%= (step_index + 1) % 2 == 0 ? 'even' : 'odd' %>">
43
+ <div>
44
+ <span class="predicate">
45
+ <%= h uniq_step.last.first.keyword %>
46
+ </span>
47
+ <span class="defined">
48
+ <%= link_transformed_step(uniq_step.last.first) %>
49
+ </span>
50
+ </div>
51
+ <% uniq_step.last.each do |step| %>
52
+ <a class="definition" style="clear: right;" href="<%= url_for step.scenario.feature %>"><%= h step.location %></a>
53
+ <% end %>
54
+ <div style="clear: both;"></div>
55
+ </div>
56
+ <% end %>
57
+ <% else %>
58
+ <div class="undefined">No steps were found to match this <%= @item_type %>.</div>
59
+ <% end%>
57
60
  </div>
58
-
59
61
  </div>
62
+
63
+ <div style="margin: 30px 20px; border-top: 1px dotted #AAA;"></div>
64
+
65
+ </div>
60
66
 
61
67
  <% end %>