lapis_lazuli 2.0.1 → 2.1.3
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.
- checksums.yaml +4 -4
- data/lapis_lazuli.gemspec +3 -2
- data/lib/lapis_lazuli/browser.rb +36 -60
- data/lib/lapis_lazuli/browser/error.rb +89 -62
- data/lib/lapis_lazuli/generators/cucumber/template/README.md +2 -0
- data/lib/lapis_lazuli/generators/cucumber/template/config/config.yml +5 -20
- data/lib/lapis_lazuli/generators/cucumber/template/config/cucumber.yml +42 -13
- data/lib/lapis_lazuli/generators/cucumber/template/config/users.yml +21 -0
- data/lib/lapis_lazuli/generators/cucumber/template/features/1_basic.feature +42 -0
- data/lib/lapis_lazuli/generators/cucumber/template/features/2_account.feature +38 -0
- data/lib/lapis_lazuli/generators/cucumber/template/features/3_todo_list.feature +23 -0
- data/lib/lapis_lazuli/generators/cucumber/template/features/helpers/authentication_helper.rb +122 -0
- data/lib/lapis_lazuli/generators/cucumber/template/features/helpers/navigation_helper.rb +64 -0
- data/lib/lapis_lazuli/generators/cucumber/template/features/helpers/registration_helper.rb +93 -0
- data/lib/lapis_lazuli/generators/cucumber/template/features/helpers/user_helper.rb +74 -0
- data/lib/lapis_lazuli/generators/cucumber/template/features/step_definitions/account_steps.rb +60 -0
- data/lib/lapis_lazuli/generators/cucumber/template/features/step_definitions/basic_steps.rb +65 -0
- data/lib/lapis_lazuli/generators/cucumber/template/features/step_definitions/todo_steps.rb +27 -0
- data/lib/lapis_lazuli/generators/cucumber/template/features/support/env.rb +3 -2
- data/lib/lapis_lazuli/options.rb +2 -1
- data/lib/lapis_lazuli/version.rb +1 -1
- data/lib/lapis_lazuli/world/config.rb +348 -334
- data/lib/lapis_lazuli/world/hooks.rb +85 -84
- data/lib/lapis_lazuli/world/logging.rb +1 -1
- data/test/config/config.yml +7 -6
- data/test/config/cucumber.yml +6 -8
- data/test/features/bindings.feature +1 -1
- data/test/features/browser.feature +1 -1
- data/test/features/step_definitions/interaction_steps.rb +5 -2
- data/test/features/step_definitions/validation_steps.rb +2 -2
- data/test/features/support/env.rb +22 -1
- data/test/results/latest_results.json +0 -0
- metadata +49 -16
- data/lib/lapis_lazuli/generators/cucumber/template/features/account.feature +0 -26
- data/lib/lapis_lazuli/generators/cucumber/template/features/example.feature +0 -30
- data/lib/lapis_lazuli/generators/cucumber/template/features/step_definitions/interaction_steps.rb +0 -165
- data/lib/lapis_lazuli/generators/cucumber/template/features/step_definitions/precondition_steps.rb +0 -63
- data/lib/lapis_lazuli/generators/cucumber/template/features/step_definitions/validation_steps.rb +0 -67
- data/lib/lapis_lazuli/generators/cucumber/template/features/support/functions.rb +0 -68
@@ -0,0 +1,21 @@
|
|
1
|
+
---
|
2
|
+
users:
|
3
|
+
default-user: # See ./features/helpers/user_helper.rb
|
4
|
+
username: ta_RAND-ALPHA_
|
5
|
+
password: Ab!2_RAND_
|
6
|
+
gender: male
|
7
|
+
experience: Ruby,Gherkin
|
8
|
+
biography: This is the default test user
|
9
|
+
complete_all: 1
|
10
|
+
production:
|
11
|
+
test-user:
|
12
|
+
username: test
|
13
|
+
password: test
|
14
|
+
test:
|
15
|
+
test-user:
|
16
|
+
username: ta-test-user
|
17
|
+
password: ^%8jah7hH
|
18
|
+
uat:
|
19
|
+
test-user:
|
20
|
+
username: ta-uat-user
|
21
|
+
password: (87hsjaJH#
|
@@ -0,0 +1,42 @@
|
|
1
|
+
@basic @all_env
|
2
|
+
Feature: Example Feature
|
3
|
+
When I want to learn how to make test cases
|
4
|
+
As a user of the test automation tool
|
5
|
+
I want to run and adjust the tests below
|
6
|
+
|
7
|
+
@basic_01
|
8
|
+
Scenario: example01 - Spritecloud search
|
9
|
+
Given the user navigates to "blog"
|
10
|
+
When the user searches for "lapis lazuli"
|
11
|
+
Then text "Open Source" should display somewhere on the page
|
12
|
+
|
13
|
+
@basic_02
|
14
|
+
Scenario: example02 - Going to a search result
|
15
|
+
Given the user navigates to "https://spritecloud.com/?s=lapis+lazuli"
|
16
|
+
When the user clicks on link "/announcing-lapislazuli/"
|
17
|
+
Then text "Let's talk about testing" should display somewhere on the page
|
18
|
+
|
19
|
+
@basic_03
|
20
|
+
Scenario Outline: example03 - checking multiple pages for the logo
|
21
|
+
Given the user navigates to "<page>"
|
22
|
+
When the user clicks on the spritecloud logo
|
23
|
+
Then the user should be on page "home"
|
24
|
+
Scenarios:
|
25
|
+
| page |
|
26
|
+
| blog |
|
27
|
+
| home |
|
28
|
+
| about-us |
|
29
|
+
| testing |
|
30
|
+
| functional-testing |
|
31
|
+
|
32
|
+
### LEARNING TO DEBUG ###
|
33
|
+
# Scenario' or Feature's including the tag @dev will be ingored when running a regular profile. To run this do:
|
34
|
+
# bundle exec cucumber -t @basic_04 -p debug
|
35
|
+
# or, if you want to test it on a specific environment:
|
36
|
+
# bundle exec cucumber -p production -p debug -t @basic_04
|
37
|
+
# Good luck fixing the problems!
|
38
|
+
@basic_04 @dev
|
39
|
+
Scenario: example_04 - confirming there is a no results page
|
40
|
+
Given the user navigates to "blog"
|
41
|
+
When the user searches for "no_results_expected"
|
42
|
+
Then the text "Nothing Found" should display on the blog page
|
@@ -0,0 +1,38 @@
|
|
1
|
+
@account @all_env
|
2
|
+
Feature: User accounts
|
3
|
+
This feature will make sure the user account functionality is working as expected
|
4
|
+
By checking registration, login and logout functionality
|
5
|
+
|
6
|
+
# This is a best practise example. Please note the following
|
7
|
+
# By defining a register, log-in and log-out state, we can easily re-use all these preconditions
|
8
|
+
# All the scenario's aren't completed, but it should be easy to implement it into your own project.
|
9
|
+
|
10
|
+
@account_01 @log_in #@pause # You can add @pause to have a break between every step.
|
11
|
+
Scenario: account_01 - Logging in
|
12
|
+
Given the user is logged out
|
13
|
+
When "test-user" logs in
|
14
|
+
Then the page should display as logged in state
|
15
|
+
|
16
|
+
@account_02 @log_out
|
17
|
+
Scenario: account_02 - Logging out
|
18
|
+
Given "test-user" is logged in
|
19
|
+
When the user clicks on the logout button
|
20
|
+
Then the page should display as logged out state
|
21
|
+
|
22
|
+
@account_03
|
23
|
+
Scenario: account_03 - Opening the registration form
|
24
|
+
Given the user is logged out
|
25
|
+
When the user clicks on the registration button
|
26
|
+
Then the registration form should display
|
27
|
+
|
28
|
+
@account_04
|
29
|
+
Scenario: account_04 - Successful registration
|
30
|
+
Given "default-user" has the registration form opened
|
31
|
+
When the user completes registration
|
32
|
+
Then the successful registration message should display
|
33
|
+
|
34
|
+
@account_05
|
35
|
+
Scenario: account_05 - Logging in a new registration
|
36
|
+
Given "default-user" has registered a new account
|
37
|
+
When the user logs in
|
38
|
+
Then the page should display as logged in state
|
@@ -0,0 +1,23 @@
|
|
1
|
+
@todo @all_env
|
2
|
+
Feature: Todo list
|
3
|
+
In this feature we will test the todo functionality
|
4
|
+
We do this by adding, completing and deleting the todo lists'
|
5
|
+
|
6
|
+
@todo_01
|
7
|
+
Scenario: todo_01 - adding a todo item
|
8
|
+
Given "test-user" is logged in
|
9
|
+
When a todo item with text "Hello world" is added
|
10
|
+
Then a todo item with text "Hello world" should be present
|
11
|
+
|
12
|
+
@todo_02
|
13
|
+
Scenario: todo_02 - removing all todo items
|
14
|
+
Given "test-user" has at least 1 todo item
|
15
|
+
When the user marks all todo items as completed
|
16
|
+
And the clear completed button is pressed
|
17
|
+
Then no todo items should display
|
18
|
+
|
19
|
+
@todo_03
|
20
|
+
Scenario: todo_03 - confirming the progress bar
|
21
|
+
Given "test-user" has exactly 8 todo items
|
22
|
+
When the user marks 4 todo items as completed
|
23
|
+
Then the progress bar should display at 50 percent
|
@@ -0,0 +1,122 @@
|
|
1
|
+
module Auth
|
2
|
+
# This is the Authentication helper, it will have all functions to log in, log out or ensure one of these statusses.
|
3
|
+
# For every part of functionality of a project, you can create a new helper, to keep your TA organised.
|
4
|
+
extend LapisLazuli
|
5
|
+
class << self
|
6
|
+
|
7
|
+
@@user = ''
|
8
|
+
@login_page = 'training-page'
|
9
|
+
|
10
|
+
# This is a list of elements relevant for this helper.
|
11
|
+
# The following is short notation, *only* use this if the element selector can be done in 1 line.
|
12
|
+
# @formatter:off
|
13
|
+
def form_container; browser.wait(:like => [:form, :id, 'form-login']); end
|
14
|
+
def username_field; form_container.input(:xpath => '//*[@id="login-username"]'); end
|
15
|
+
def password_field; form_container.input(:id => 'login-password'); end
|
16
|
+
def login_button; browser.button(:id => 'button-login'); end
|
17
|
+
# @formatter:on
|
18
|
+
|
19
|
+
# Following elements that need more advanced options/search patterns
|
20
|
+
def logged_in_element(timeout=10, throw=true)
|
21
|
+
browser.wait(
|
22
|
+
:like => [:a, :id, 'user_dropdown'],
|
23
|
+
:timeout => timeout,
|
24
|
+
:throw => throw
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
def logged_out_element(timeout=10, throw=true)
|
29
|
+
browser.wait(
|
30
|
+
:like => [:form, :id, 'form-login'],
|
31
|
+
:timeout => timeout,
|
32
|
+
:throw => throw
|
33
|
+
)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Next are the functions called from the step definitions
|
37
|
+
# `ensure_something` is best practise to be used for functions that should get the test to a certain state. For example:
|
38
|
+
# `ensure_log_out` only logs out if you're logged in
|
39
|
+
# `log_out` will blindly try to log out and fail if you're already logged out
|
40
|
+
def ensure_log_out
|
41
|
+
Nav.to('training-page')
|
42
|
+
if Auth.is_logged_in?
|
43
|
+
Auth.log_out
|
44
|
+
if Auth.is_logged_in?
|
45
|
+
error 'Page did not display in logged out state after logging out'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Makes sure that a specific user is logged in, if it's not already.
|
51
|
+
def ensure_log_in(user='default-user')
|
52
|
+
Nav.to('training-page')
|
53
|
+
unless Auth.is_logged_in?(user)
|
54
|
+
# If the wrong user is logged in, we should ensure a log out action and then log in again
|
55
|
+
Auth.ensure_log_out
|
56
|
+
Auth.log_in(user)
|
57
|
+
# Double check if the login was successful, if not, throw an error.
|
58
|
+
unless Auth.is_logged_in?(user)
|
59
|
+
error "Failed to log in `#{user}`."
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# If user=nil, any logged in user is acceptable, else we want to make sure the username matches with the logged in user.
|
65
|
+
def is_logged_in?(user=nil)
|
66
|
+
# For performance, we do a 0 second wait for the logged_out_element
|
67
|
+
if Auth.logged_out_element(0, false)
|
68
|
+
return false
|
69
|
+
end
|
70
|
+
login_elm = Auth.logged_in_element(5, false)
|
71
|
+
if login_elm.nil?
|
72
|
+
# Logged in element not found, check if the logged out element is present
|
73
|
+
logout_elm = Auth.logged_out_element(0, false)
|
74
|
+
if logout_elm.nil?
|
75
|
+
# Neither of the elements were present, this should not be possible.
|
76
|
+
error 'Failed to find the logged_out element and the logged_in element. The user is not logged in, nor logged out.'
|
77
|
+
else
|
78
|
+
# Logged out element was found the second time.
|
79
|
+
return false
|
80
|
+
end
|
81
|
+
else
|
82
|
+
# The logged in element was found, should we match the username?
|
83
|
+
if user.nil?
|
84
|
+
# No, any user is fine
|
85
|
+
return true
|
86
|
+
else
|
87
|
+
# Yes, load the user data and match the username
|
88
|
+
User.load_user_data(user)
|
89
|
+
return login_elm.span(:class => ['username', 'ng-binding']).text == User.get('username')
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def log_out
|
95
|
+
Auth.logged_in_element.click
|
96
|
+
dropdown = browser.wait(:like => [:ul, :class, 'dropdown-menu'])
|
97
|
+
browser.find(
|
98
|
+
:like => [:a, :id, 'link-logout'],
|
99
|
+
:context => dropdown
|
100
|
+
).click
|
101
|
+
end
|
102
|
+
|
103
|
+
def log_in(user=nil, renew_session=false)
|
104
|
+
# If user=nil, we expect that there already is user data loaded in a previous step.
|
105
|
+
User.load_user_data(user) unless user.nil?
|
106
|
+
|
107
|
+
Auth.username_field.to_subtype.set(User.get('username'))
|
108
|
+
Auth.password_field.to_subtype.set(User.get('password'))
|
109
|
+
Auth.login_button.click
|
110
|
+
|
111
|
+
unless Auth.is_logged_in? user
|
112
|
+
alert = browser.find(:like => [:div, :class, 'alert'], :throw => false)
|
113
|
+
if alert.nil?
|
114
|
+
error "Failed to log in user #{user}"
|
115
|
+
else
|
116
|
+
alert.flash
|
117
|
+
error "Found error while logging in #{user}: `#{alert.text}`"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# Simple helper that makes navigating using the config file easier
|
2
|
+
# It will check if a given string is a URL or a config value and goto that page accordingly
|
3
|
+
module Nav
|
4
|
+
extend LapisLazuli
|
5
|
+
class << self
|
6
|
+
|
7
|
+
# Navigates to a given URL or page.url configuration if the current URL is not the same
|
8
|
+
# Then confirms that the new URL is loaded.
|
9
|
+
def to(config_page_or_url, force_refresh = false)
|
10
|
+
url = self.set_url(config_page_or_url)
|
11
|
+
browser.goto url unless url == browser.url and !force_refresh
|
12
|
+
Nav.wait_for_url url
|
13
|
+
end
|
14
|
+
|
15
|
+
# Waits until the browser URL is the same as the given URL
|
16
|
+
def wait_for_url(url)
|
17
|
+
browser.wait_until(timeout: 5, message: "URL did not become `#{url}`") {
|
18
|
+
browser.url.include? url
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
# Loads the URL from the config, prioritized from top to bottom:
|
23
|
+
# production.pages.home
|
24
|
+
# production.pages.home.path
|
25
|
+
# pages.home
|
26
|
+
# pages.home.path
|
27
|
+
def get_url page
|
28
|
+
begin
|
29
|
+
return env_or_config("pages.#{page}")
|
30
|
+
rescue RuntimeError
|
31
|
+
return env_or_config("pages.#{page}.path")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Confirms if the given URL is a valid URL
|
36
|
+
def is_url? string
|
37
|
+
uri = URI.parse(string)
|
38
|
+
%w( http https ).include?(uri.scheme)
|
39
|
+
rescue URI::BadURIError
|
40
|
+
false
|
41
|
+
rescue URI::InvalidURIError
|
42
|
+
false
|
43
|
+
end
|
44
|
+
|
45
|
+
# returns the expected URL
|
46
|
+
def set_url(config_page_or_url)
|
47
|
+
if Nav.is_url? config_page_or_url
|
48
|
+
# Return the given URL if it alreadt is a valid URL
|
49
|
+
return config_page_or_url
|
50
|
+
else
|
51
|
+
# Look for the URL in the config files
|
52
|
+
path_or_url = get_url config_page_or_url
|
53
|
+
if Nav.is_url? path_or_url
|
54
|
+
# If it is a URL now, then return it
|
55
|
+
return path_or_url
|
56
|
+
else
|
57
|
+
# Else add an expected 'root' to the path.
|
58
|
+
return env('root') + path_or_url
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
module Register
|
2
|
+
|
3
|
+
extend LapisLazuli
|
4
|
+
class << self
|
5
|
+
|
6
|
+
# This is a list of elements relevant for this helper.
|
7
|
+
# The following is short notation, *only* use this if the element selector can be done in 1 line.
|
8
|
+
# @formatter:off
|
9
|
+
def form; browser.wait(:like => [:form, :id, 'form-register']); end
|
10
|
+
def open_register_button; browser.find(:like => [:button, :id, 'button-register']); end
|
11
|
+
def username_field; browser.find(:element => {:name => 'username'}, :context => Register.form); end
|
12
|
+
def password_field; browser.find(:element => {:name => 'password'}, :context => Register.form); end
|
13
|
+
def experience_field; browser.find(:like => [:select, :id, "register-experience"], :context => form); end
|
14
|
+
def biography_field; browser.find(:like => [:textarea, :id, 'register-bio']); end
|
15
|
+
def policy_checkbox; browser.find(:like => [:input, :id, 'register-complete-all']) end
|
16
|
+
def submit_button; browser.find(:button => {:id => 'button-save'}, :context => Register.form); end
|
17
|
+
# @formatter:on
|
18
|
+
|
19
|
+
def gender_radio(gender)
|
20
|
+
browser.find(
|
21
|
+
:label => {:text => /#{gender}/i},
|
22
|
+
:context => Register.form,
|
23
|
+
:message => "Unable to find gender `#{gender}`, are you sure it's an option to select?"
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
def select_experiences(*experience_list)
|
28
|
+
experience_list.each do |exp|
|
29
|
+
option = browser.find(
|
30
|
+
:option => {:value => /#{exp}/i},
|
31
|
+
:context => Register.experience_field
|
32
|
+
)
|
33
|
+
option.click(:control)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# The following 3 functions are a typical example of something to use.
|
38
|
+
# First a function in which you perform an action (open_something, click_something, press_something)
|
39
|
+
def open_registration
|
40
|
+
Register.open_register_button.click
|
41
|
+
end
|
42
|
+
|
43
|
+
# Second, a function that confirms that the action was successful
|
44
|
+
def is_registration_open?
|
45
|
+
return Register.form rescue false
|
46
|
+
end
|
47
|
+
|
48
|
+
# And finally as function that ensures an action was successfully completed.
|
49
|
+
def ensure_open_registrarion
|
50
|
+
Auth.ensure_log_out
|
51
|
+
Register.open_registration unless Register.is_registration_open?
|
52
|
+
end
|
53
|
+
|
54
|
+
def fill_form
|
55
|
+
Register.username_field.set(User.get('username'))
|
56
|
+
Register.password_field.set(User.get('password'))
|
57
|
+
Register.gender_radio(User.get('gender')).click
|
58
|
+
Register.select_experiences(User.get('experience').split(','))
|
59
|
+
Register.biography_field.set(User.get('biography'))
|
60
|
+
Register.policy_checkbox.set((User.get('complete_all').to_i == 1))
|
61
|
+
end
|
62
|
+
|
63
|
+
def submit_form
|
64
|
+
Register.submit_button.click
|
65
|
+
end
|
66
|
+
|
67
|
+
def register_user
|
68
|
+
Register.fill_form
|
69
|
+
Register.submit_form
|
70
|
+
end
|
71
|
+
|
72
|
+
def registration_result
|
73
|
+
alert = browser.wait(like: [:div, :class, 'alert'], timeout: 2, throw: false)
|
74
|
+
if alert.nil?
|
75
|
+
return false, 'No message was displayed after registering'
|
76
|
+
elsif !alert.text.include? User.get('username')
|
77
|
+
return false, "An error message did display, but didn't contain the expected text: `#{alert.text}`"
|
78
|
+
end
|
79
|
+
return true, 'Successfully found the success message'
|
80
|
+
end
|
81
|
+
|
82
|
+
def ensure_registered(user)
|
83
|
+
begin
|
84
|
+
Auth.ensure_log_in(user)
|
85
|
+
Auth.log_out
|
86
|
+
rescue Exception => e
|
87
|
+
Register.ensure_open_registrarion
|
88
|
+
Register.register_user
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# This helper loads user data from the config files.
|
2
|
+
# After loading the data, it will overwrite certain strings, like __TIMESTAMP__ to randomize information
|
3
|
+
module User
|
4
|
+
extend LapisLazuli
|
5
|
+
|
6
|
+
class << self
|
7
|
+
@@data = nil
|
8
|
+
|
9
|
+
def load_user_data(user)
|
10
|
+
data = config('users.default-user')
|
11
|
+
begin
|
12
|
+
specific_data = config("users.#{user}")
|
13
|
+
rescue Exception => err1
|
14
|
+
begin
|
15
|
+
specific_data = config("users.#{ENV['TEST_ENV']}.#{user}")
|
16
|
+
rescue Exception => err2
|
17
|
+
error "The given user `#{user}` was not found in any of the config files:\n- #{err1.message}\n- #{err2.message}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
new_data = data.merge specific_data
|
21
|
+
@@data = replace_hash_constants(new_data)
|
22
|
+
end
|
23
|
+
|
24
|
+
def get(field)
|
25
|
+
return @@data[field]
|
26
|
+
end
|
27
|
+
|
28
|
+
def set(field, value)
|
29
|
+
@@data[field] = User.replace_constants(value)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Replace random or time values of a complete hash
|
33
|
+
def replace_hash_constants(hash)
|
34
|
+
if hash.respond_to? :each
|
35
|
+
new_hash = {}
|
36
|
+
hash.each do |key, value|
|
37
|
+
new_hash[key] = replace_constants(value)
|
38
|
+
end
|
39
|
+
else
|
40
|
+
new_hash = replace_constants(hash)
|
41
|
+
end
|
42
|
+
return new_hash
|
43
|
+
end
|
44
|
+
|
45
|
+
# replace certain constants in a string, for example '_TIMESTAMP_' becomes '154875631'
|
46
|
+
def replace_constants(value)
|
47
|
+
if value.to_s == value
|
48
|
+
epoch = Time.now.to_i
|
49
|
+
alpha = number_to_letter(epoch)
|
50
|
+
timestamp = Time.now.strftime("D%Y-%M-%d-T%H-%M-%S")
|
51
|
+
|
52
|
+
old_val = value.to_s
|
53
|
+
value = value.sub('_RAND_', epoch.to_s)
|
54
|
+
value = value.sub('_TIMESTAMP_', timestamp)
|
55
|
+
value = value.sub('_RAND-ALPHA_', alpha)
|
56
|
+
unless value == old_val
|
57
|
+
log.debug "#{old_val} > #{value}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
return value
|
61
|
+
end
|
62
|
+
|
63
|
+
def number_to_letter(numbers)
|
64
|
+
num_string = numbers.to_s
|
65
|
+
alpha26 = ("a".."j").to_a
|
66
|
+
letters = ''
|
67
|
+
num_string.scan(/./).each do |number|
|
68
|
+
letters += alpha26[number.to_i]
|
69
|
+
end
|
70
|
+
return letters
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|