selenium_plus 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/features/drivers.feature +3 -6
- data/features/element.feature +22 -0
- data/features/finders.feature +24 -11
- data/features/select.feature +3 -5
- data/features/step_definitions/element_steps.rb +28 -0
- data/features/step_definitions/finder_steps.rb +17 -4
- data/lib/selenium_plus/driver.rb +1 -1
- data/lib/selenium_plus/finders.rb +0 -12
- data/lib/selenium_plus/page_obj/page.rb +1 -1
- data/lib/selenium_plus/page_obj/section.rb +1 -1
- data/lib/selenium_plus/selenium/element.rb +4 -17
- data/lib/selenium_plus/version.rb +1 -1
- data/lib/selenium_plus.rb +6 -4
- data/selenium_plus.gemspec +1 -1
- data/test_site/html/home.html +27 -4
- data/test_site/pages/home_page.rb +28 -0
- data/test_site/sections/info_section.rb +6 -1
- metadata +17 -13
data/features/drivers.feature
CHANGED
@@ -1,29 +1,26 @@
|
|
1
1
|
Feature: Verify drivers
|
2
2
|
|
3
|
+
Background:
|
4
|
+
When I login to home page
|
5
|
+
|
3
6
|
@firefox
|
4
7
|
Scenario: Verify using @firefox tag calls firefox driver
|
5
|
-
When I login to home page
|
6
8
|
Then Current browser should be firefox
|
7
9
|
|
8
10
|
@chrome
|
9
11
|
Scenario: navigate using @chrome tag calls chrome driver
|
10
|
-
When I login to home page
|
11
12
|
Then Current browser should be chrome
|
12
13
|
|
13
14
|
Scenario: Verify execute script
|
14
|
-
When I login to home page
|
15
15
|
And I execute script: document.activeElement.style.border='2px solid red'
|
16
16
|
|
17
17
|
Scenario: Verify evaluate script
|
18
|
-
When I login to home page
|
19
18
|
Then I evaluate script: document.getElementById('home_title').textContent
|
20
19
|
And Evaluate value should be: Test Home Page
|
21
20
|
|
22
21
|
Scenario: Verify save a screen shot
|
23
|
-
When I login to home page
|
24
22
|
Then I save a screenshot
|
25
23
|
|
26
24
|
Scenario: Verify save a screen shot
|
27
|
-
When I login to home page
|
28
25
|
And I click show button
|
29
26
|
Then Active element value should be: Show
|
@@ -0,0 +1,22 @@
|
|
1
|
+
Feature: Verify Element Class
|
2
|
+
|
3
|
+
Background:
|
4
|
+
When I login to home page
|
5
|
+
|
6
|
+
Scenario: Verify element existence
|
7
|
+
And Element show_btn should exist
|
8
|
+
|
9
|
+
Scenario: Get element attribute value
|
10
|
+
Then Show btn name attribute value should be: Show First Table
|
11
|
+
And Show btn type attribute value should be: submit
|
12
|
+
And Show btn value attribute value should be: Show
|
13
|
+
And Show btn not_exit attribute value should be: nil
|
14
|
+
|
15
|
+
Scenario: Verify Element visibility
|
16
|
+
Then Horizontal header table should be invisible
|
17
|
+
And Vertical header table should be visible
|
18
|
+
|
19
|
+
Scenario: Verify append text
|
20
|
+
When I add world in test input element
|
21
|
+
Then I should see hello world in test input element
|
22
|
+
|
data/features/finders.feature
CHANGED
@@ -1,19 +1,32 @@
|
|
1
1
|
Feature: Verify finders
|
2
2
|
|
3
|
-
|
3
|
+
Background:
|
4
4
|
When I login to home page
|
5
|
-
And Title inside div#info should be: Information tables
|
6
5
|
|
7
6
|
Scenario: Verify find element using element.find
|
8
|
-
|
9
|
-
And Title outside div#info should be: Test Home Page
|
7
|
+
Then Country span inside div#contact should be: US
|
10
8
|
|
11
|
-
Scenario: Verify element
|
12
|
-
|
13
|
-
|
9
|
+
Scenario: Verify find element using section.find
|
10
|
+
Then Title inside div#info should be: Information tables
|
11
|
+
|
12
|
+
Scenario: Verify find element using driver.find
|
13
|
+
Then Title outside div#info should be: Test Home Page
|
14
|
+
|
15
|
+
Scenario: Verify find elements using element.all
|
16
|
+
Then Contact spans inside div#contact should be:
|
17
|
+
| US |
|
18
|
+
| AK |
|
14
19
|
|
15
20
|
Scenario: Verify find elements using driver.all
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
21
|
+
Then Page titles should be:
|
22
|
+
| Test Home Page |
|
23
|
+
| Information tables |
|
24
|
+
| Table with no header |
|
25
|
+
| Table with no body |
|
26
|
+
|
27
|
+
Scenario: Verify find elements using section.all
|
28
|
+
Then Section titles should be:
|
29
|
+
| Information tables |
|
30
|
+
| Table with no header |
|
31
|
+
| Table with no body |
|
32
|
+
|
data/features/select.feature
CHANGED
@@ -1,28 +1,26 @@
|
|
1
1
|
Feature: Verify Select Element
|
2
2
|
|
3
|
-
|
3
|
+
Background:
|
4
4
|
When I login to home page
|
5
|
+
|
6
|
+
Scenario: Verify Select Options
|
5
7
|
Then Single select 'select_options' should be:
|
6
8
|
| Volvo | Saab | Mercedes | Audi |
|
7
9
|
|
8
10
|
Scenario: Verify Select Options Value
|
9
|
-
When I login to home page
|
10
11
|
Then Single select 'select_value' should be:
|
11
12
|
| 1 | 2 | 3 | 4 |
|
12
13
|
|
13
14
|
Scenario: Verify Select first selected option
|
14
|
-
When I login to home page
|
15
15
|
Then Single select 'first_selected_option' should be: Mercedes
|
16
16
|
|
17
17
|
Scenario: Verify Multi Selected Options
|
18
|
-
When I login to home page
|
19
18
|
And I select Volvo in multi select
|
20
19
|
And I select Mercedes in multi select
|
21
20
|
Then Multi select 'selected_options' should be:
|
22
21
|
| Volvo | Mercedes |
|
23
22
|
|
24
23
|
Scenario: Verify Single Selected Option
|
25
|
-
When I login to home page
|
26
24
|
And I select Audi in single select
|
27
25
|
Then Single select 'selected_options' should be:
|
28
26
|
| Audi |
|
@@ -0,0 +1,28 @@
|
|
1
|
+
Then /^Show btn (.+) attribute value should be: (.+)$/ do |attribute, value|
|
2
|
+
if value == 'nil'
|
3
|
+
@site.home_page.show_btn[attribute].should == nil
|
4
|
+
else
|
5
|
+
@site.home_page.show_btn[attribute].should == value
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
Then /^Horizontal header table should be invisible$/ do
|
10
|
+
@site.home_page.info_section.h_table.visible?.should be_false
|
11
|
+
end
|
12
|
+
|
13
|
+
Then /^Vertical header table should be visible$/ do
|
14
|
+
@site.home_page.info_section.v_table.visible?.should be_true
|
15
|
+
end
|
16
|
+
|
17
|
+
Then /^Element show_btn should exist$/ do
|
18
|
+
@site.home_page.has_show_btn?.should be_true
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
When /^I add (.+) in test input element$/ do |text|
|
23
|
+
@site.home_page.append_text(text)
|
24
|
+
end
|
25
|
+
|
26
|
+
Then /^I should see (.+) in test input element$/ do |text|
|
27
|
+
@site.home_page.text_after.should == text
|
28
|
+
end
|
@@ -4,13 +4,26 @@ Then /^Title (inside|outside) div#info should be: (.+)$/ do |where, title|
|
|
4
4
|
@site.home_page.info_section.title.should == title
|
5
5
|
when 'outside'
|
6
6
|
@site.home_page.title.should == title
|
7
|
+
else
|
8
|
+
# Skipped
|
7
9
|
end
|
8
10
|
end
|
9
11
|
|
10
|
-
Then /^
|
11
|
-
|
12
|
+
Then /^(Page|Section) titles should be:$/ do |type, titles_table|
|
13
|
+
case type
|
14
|
+
when 'Page'
|
15
|
+
@site.home_page.titles.should == titles_table.raw.flatten
|
16
|
+
when 'Section'
|
17
|
+
@site.home_page.info_section.titles.should == titles_table.raw.flatten
|
18
|
+
else
|
19
|
+
# Skipped
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
Then /^Country span inside div#contact should be: (.+)$/ do |value|
|
24
|
+
@site.home_page.country.should == value
|
12
25
|
end
|
13
26
|
|
14
|
-
Then /^
|
15
|
-
@site.home_page.
|
27
|
+
Then /^Contact spans inside div#contact should be:$/ do |table|
|
28
|
+
@site.home_page.contact.should == table.raw.flatten
|
16
29
|
end
|
data/lib/selenium_plus/driver.rb
CHANGED
@@ -40,7 +40,7 @@ module SeleniumPlus
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def highlight_element(element)
|
43
|
-
native.execute_script("arguments[0].setAttribute('style', 'border: 2px solid red;')", element)
|
43
|
+
native.execute_script("arguments[0].setAttribute('style', '#{element[:style]}; border: 2px solid red;')", element)
|
44
44
|
end
|
45
45
|
|
46
46
|
def execute_script(script)
|
@@ -21,17 +21,5 @@ module SeleniumPlus
|
|
21
21
|
SeleniumPlus.driver.native.find_elements(*args)
|
22
22
|
end
|
23
23
|
end
|
24
|
-
|
25
|
-
def not_find(*args)
|
26
|
-
begin
|
27
|
-
if self.class.superclass == SeleniumPlus::Section
|
28
|
-
root_element.find_element(*args)
|
29
|
-
else
|
30
|
-
SeleniumPlus.driver.native.find_element(*args)
|
31
|
-
end
|
32
|
-
rescue Selenium::WebDriver::Error::NoSuchElementError
|
33
|
-
# Expected
|
34
|
-
end
|
35
|
-
end
|
36
24
|
end
|
37
25
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# Public: Add extension method to Element class
|
2
2
|
#
|
3
3
|
class Selenium::WebDriver::Element
|
4
|
+
include SeleniumPlus::Finders
|
4
5
|
include SeleniumPlus::Elements::Table
|
5
6
|
include SeleniumPlus::Elements::Select
|
6
7
|
|
@@ -14,12 +15,10 @@ class Selenium::WebDriver::Element
|
|
14
15
|
# @return [String] The value of the attribute
|
15
16
|
def [](attribute)
|
16
17
|
self.attribute(attribute.to_s)
|
17
|
-
rescue Selenium::WebDriver::Error::WebDriverError
|
18
|
-
nil
|
19
18
|
end
|
20
19
|
|
21
20
|
def visible?
|
22
|
-
self.
|
21
|
+
self.displayed?
|
23
22
|
end
|
24
23
|
|
25
24
|
# Set the value of the element to the given value.
|
@@ -32,18 +31,7 @@ class Selenium::WebDriver::Element
|
|
32
31
|
# @return []
|
33
32
|
def set(value)
|
34
33
|
tag_name = self.tag_name
|
35
|
-
|
36
|
-
if (Array === value) && !self[:multiple]
|
37
|
-
raise ArgumentError.new "Value cannot be an Array when 'multiple' attribute is not present. Not a #{value.class}"
|
38
|
-
end
|
39
|
-
if tag_name == 'input' and type == 'radio'
|
40
|
-
click
|
41
|
-
elsif tag_name == 'input' and type == 'checkbox'
|
42
|
-
click if value ^ native.attribute('checked').to_s.eql?('true')
|
43
|
-
elsif tag_name == 'input' and type == 'file'
|
44
|
-
path_names = value.to_s.empty? ? [] : value
|
45
|
-
self.send_keys(*path_names)
|
46
|
-
elsif tag_name == 'textarea' or tag_name == 'input'
|
34
|
+
if tag_name == 'textarea' or tag_name == 'input'
|
47
35
|
self.send_keys(value.to_s)
|
48
36
|
end
|
49
37
|
end
|
@@ -70,7 +58,6 @@ class Selenium::WebDriver::Element
|
|
70
58
|
#
|
71
59
|
# @return []
|
72
60
|
def append(text)
|
73
|
-
|
74
|
-
self.set(old + text)
|
61
|
+
self.set("#{self.text} #{text}")
|
75
62
|
end
|
76
63
|
end
|
data/lib/selenium_plus.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
$:.unshift(File.dirname(__FILE__))
|
2
2
|
|
3
|
-
|
3
|
+
if ENV['COVERAGE']
|
4
|
+
require 'simplecov'
|
4
5
|
|
5
|
-
SimpleCov.start do
|
6
|
-
|
7
|
-
|
6
|
+
SimpleCov.start do
|
7
|
+
add_group 'Libraries', 'lib'
|
8
|
+
add_group 'Features', 'features'
|
9
|
+
end
|
8
10
|
end
|
9
11
|
|
10
12
|
require 'logger'
|
data/selenium_plus.gemspec
CHANGED
@@ -20,6 +20,6 @@ Gem::Specification.new do |gem|
|
|
20
20
|
gem.add_dependency('rake')
|
21
21
|
gem.add_dependency('selenium-webdriver', ['>= 2.25.0'])
|
22
22
|
gem.add_dependency('rspec', ['>= 2.1.0'])
|
23
|
-
gem.
|
23
|
+
gem.add_development_dependency('simplecov', ['>= 0.7.1'])
|
24
24
|
gem.add_development_dependency('cucumber', ['>= 1.2.1'])
|
25
25
|
end
|
data/test_site/html/home.html
CHANGED
@@ -16,7 +16,7 @@
|
|
16
16
|
</head>
|
17
17
|
<body>
|
18
18
|
<div id="home_title" class="title">Test Home Page</div>
|
19
|
-
<input type="submit" name="Show First Table" value="Show" onclick="showFirstTable(
|
19
|
+
<input type="submit" name="Show First Table" value="Show" onclick="showFirstTable('first')"/>
|
20
20
|
<div id="info">
|
21
21
|
<div class="title">Information tables</div>
|
22
22
|
<table id="first" class="horizontal_headers" style="display: none">
|
@@ -36,7 +36,7 @@
|
|
36
36
|
<td>EMC</td>
|
37
37
|
</tr>
|
38
38
|
</table>
|
39
|
-
<table class="vertical_headers">
|
39
|
+
<table id="second" class="vertical_headers">
|
40
40
|
<tr>
|
41
41
|
<th>ID:</th>
|
42
42
|
<td>1</td>
|
@@ -53,7 +53,7 @@
|
|
53
53
|
<td>Microsoft</td>
|
54
54
|
</tr>
|
55
55
|
</table>
|
56
|
-
<div>Table with no header</div>
|
56
|
+
<div class="title">Table with no header</div>
|
57
57
|
<table class="no_headers">
|
58
58
|
<tr>
|
59
59
|
<th>ID:</th>
|
@@ -61,7 +61,7 @@
|
|
61
61
|
<th>Company:</th>
|
62
62
|
</tr>
|
63
63
|
</table>
|
64
|
-
<div>Table with no body</div>
|
64
|
+
<div class="title">Table with no body</div>
|
65
65
|
<table class="no_body">
|
66
66
|
<tr>
|
67
67
|
<td>1</td>
|
@@ -88,6 +88,29 @@
|
|
88
88
|
<option value="opel">Mercedes</option>
|
89
89
|
<option value="audi">Audi</option>
|
90
90
|
</select>
|
91
|
+
<div id="contact">
|
92
|
+
<div id="address">
|
93
|
+
<span class="country">US</span>
|
94
|
+
<span class="state">AK</span>
|
95
|
+
</div>
|
96
|
+
</div>
|
97
|
+
<div id="append">Append Test
|
98
|
+
<input type="text" value="hello" />
|
99
|
+
</div>
|
91
100
|
|
101
|
+
<form>
|
102
|
+
<div>Radio Button Test</div>
|
103
|
+
<input type="radio" name="sex" value="male">Male<br>
|
104
|
+
<input type="radio" name="sex" value="female">Female
|
105
|
+
</form>
|
106
|
+
<form>
|
107
|
+
<div>Check Box Test</div>
|
108
|
+
<input type="checkbox" name="vehicle" value="Bike">I have a bike<br>
|
109
|
+
<input type="checkbox" name="vehicle" value="Car">I have a car
|
110
|
+
</form>
|
111
|
+
<form>
|
112
|
+
<div>File Test</div>
|
113
|
+
<input type="file" name="file_name" />
|
114
|
+
</form>
|
92
115
|
</body>
|
93
116
|
</html>
|
@@ -7,7 +7,18 @@ module Test
|
|
7
7
|
element(:title_div, :css, 'div.title')
|
8
8
|
element(:single_select, :id, 'single_select')
|
9
9
|
element(:multi_select, :id, 'multi_select')
|
10
|
+
element(:contact_div, :id, 'contact')
|
10
11
|
elements(:title_divs, :css, 'div.title')
|
12
|
+
element(:not_found_div, :css, 'div.not_found')
|
13
|
+
element(:append_input, :css, 'div#append input')
|
14
|
+
# Radio elements
|
15
|
+
element(:male_radio, :css, 'input[value=male]')
|
16
|
+
element(:female_radio, :css, 'input[value=female]')
|
17
|
+
# Check box elements
|
18
|
+
element(:bike_checkbox, :css, 'input[value=Bike]')
|
19
|
+
element(:car_checkbox, :css, 'input[value=Car]')
|
20
|
+
# File element
|
21
|
+
element(:file_input, :css, 'input[name=file_name]')
|
11
22
|
|
12
23
|
def show_first_table
|
13
24
|
show_btn.click
|
@@ -20,6 +31,23 @@ module Test
|
|
20
31
|
def titles
|
21
32
|
title_divs.map{ |cell| cell.text.strip }
|
22
33
|
end
|
34
|
+
|
35
|
+
def country
|
36
|
+
contact_div.find(:id,'address').find(:css, 'span.country').text
|
37
|
+
end
|
38
|
+
|
39
|
+
def contact
|
40
|
+
el = contact_div
|
41
|
+
el.all(:css, 'span').map{ |e| e.text}
|
42
|
+
end
|
43
|
+
|
44
|
+
def append_text(text)
|
45
|
+
append_input.append(text)
|
46
|
+
end
|
47
|
+
|
48
|
+
def text_after
|
49
|
+
append_input[:value]
|
50
|
+
end
|
23
51
|
end
|
24
52
|
end
|
25
53
|
|
@@ -7,9 +7,14 @@ module Test
|
|
7
7
|
element(:no_headers_table, :css, 'table.no_headers')
|
8
8
|
element(:no_body_table, :css, 'table.no_body')
|
9
9
|
element(:title_div, :css, 'div.title')
|
10
|
-
|
10
|
+
elements(:all_title_div, :css, 'div.title')
|
11
11
|
def title
|
12
12
|
title_div.text
|
13
13
|
end
|
14
|
+
|
15
|
+
def titles
|
16
|
+
all_title_div.map{ |el| el.text }
|
17
|
+
end
|
18
|
+
|
14
19
|
end
|
15
20
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: selenium_plus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-03-
|
12
|
+
date: 2013-03-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
16
|
-
requirement: &
|
16
|
+
requirement: &70113823561660 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70113823561660
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: selenium-webdriver
|
27
|
-
requirement: &
|
27
|
+
requirement: &70113823560380 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 2.25.0
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70113823560380
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rspec
|
38
|
-
requirement: &
|
38
|
+
requirement: &70113823559460 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,21 +43,21 @@ dependencies:
|
|
43
43
|
version: 2.1.0
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70113823559460
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: simplecov
|
49
|
-
requirement: &
|
49
|
+
requirement: &70113823558400 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: 0.7.1
|
55
|
-
type: :
|
55
|
+
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70113823558400
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: cucumber
|
60
|
-
requirement: &
|
60
|
+
requirement: &70113823557500 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,7 +65,7 @@ dependencies:
|
|
65
65
|
version: 1.2.1
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70113823557500
|
69
69
|
description: SeleniumPlus creates a very thin layer between Selenium and your applications,
|
70
70
|
it gives your a simple and quick way to describe your web site using the Page Object
|
71
71
|
Model.
|
@@ -81,9 +81,11 @@ files:
|
|
81
81
|
- README.md
|
82
82
|
- Rakefile
|
83
83
|
- features/drivers.feature
|
84
|
+
- features/element.feature
|
84
85
|
- features/finders.feature
|
85
86
|
- features/select.feature
|
86
87
|
- features/step_definitions/drivers_steps.rb
|
88
|
+
- features/step_definitions/element_steps.rb
|
87
89
|
- features/step_definitions/finder_steps.rb
|
88
90
|
- features/step_definitions/general_steps.rb
|
89
91
|
- features/step_definitions/select_steps.rb
|
@@ -137,9 +139,11 @@ specification_version: 3
|
|
137
139
|
summary: ''
|
138
140
|
test_files:
|
139
141
|
- features/drivers.feature
|
142
|
+
- features/element.feature
|
140
143
|
- features/finders.feature
|
141
144
|
- features/select.feature
|
142
145
|
- features/step_definitions/drivers_steps.rb
|
146
|
+
- features/step_definitions/element_steps.rb
|
143
147
|
- features/step_definitions/finder_steps.rb
|
144
148
|
- features/step_definitions/general_steps.rb
|
145
149
|
- features/step_definitions/select_steps.rb
|