lapis_lazuli 2.0.1 → 3.0.0
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 +5 -5
- data/README.md +1 -1
- data/lapis_lazuli.gemspec +10 -8
- data/lib/lapis_lazuli/api.rb +1 -1
- data/lib/lapis_lazuli/argparse.rb +1 -1
- data/lib/lapis_lazuli/browser.rb +37 -61
- data/lib/lapis_lazuli/browser/error.rb +89 -62
- data/lib/lapis_lazuli/browser/find.rb +1 -2
- data/lib/lapis_lazuli/cli.rb +1 -1
- data/lib/lapis_lazuli/cucumber.rb +1 -1
- data/lib/lapis_lazuli/generators/cucumber.rb +1 -1
- data/lib/lapis_lazuli/generators/cucumber/template/README.md +2 -0
- data/lib/lapis_lazuli/generators/cucumber/template/config/config.yml +6 -21
- 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 +49 -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 +102 -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 +70 -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/generic/xpath.rb +1 -1
- data/lib/lapis_lazuli/options.rb +3 -2
- data/lib/lapis_lazuli/placeholders.rb +1 -1
- data/lib/lapis_lazuli/proxy.rb +1 -1
- data/lib/lapis_lazuli/runtime.rb +1 -1
- data/lib/lapis_lazuli/scenario.rb +1 -1
- data/lib/lapis_lazuli/storage.rb +1 -1
- data/lib/lapis_lazuli/version.rb +2 -2
- data/lib/lapis_lazuli/versions.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/Gemfile +2 -16
- 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 +21 -1
- data/test/results/latest_results.json +0 -0
- metadata +74 -28
- 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
@@ -24,39 +24,24 @@ error_strings:
|
|
24
24
|
################################################################################
|
25
25
|
# Environment specific variables
|
26
26
|
test:
|
27
|
+
root: http://username:password@test.spritecloud.com #Not an existing page, note the username/password user inside the URL
|
27
28
|
pages:
|
28
|
-
root: http://username:password@test.spritecloud.com #Not an existing page, note the username/password user inside the URL
|
29
29
|
home: /
|
30
30
|
about-us: /about-us/
|
31
31
|
|
32
32
|
uat:
|
33
|
+
root: http://username:password@uat.spritecloud.com #Not an existing page, note the username/password user inside the URL
|
33
34
|
pages:
|
34
|
-
root: http://username:password@uat.spritecloud.com #Not an existing page, note the username/password user inside the URL
|
35
35
|
home: /
|
36
36
|
about-us: /about-us/
|
37
37
|
|
38
38
|
production:
|
39
|
+
root: https://www.spritecloud.com
|
39
40
|
pages:
|
40
|
-
root: https://www.spritecloud.com
|
41
41
|
home: /
|
42
42
|
about-us: /about-us/
|
43
43
|
testing: /testing/
|
44
44
|
blog: /blog/
|
45
|
-
functional-testing: /testing/functional/
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
# Different user variables
|
50
|
-
users:
|
51
|
-
default-user: # These are the default variable settings. If no setting was specified, these values will be used.
|
52
|
-
username: test
|
53
|
-
password: test
|
54
|
-
gender: 'Male'
|
55
|
-
experience: 'Ruby,Cucumber,HTML,XPath'
|
56
|
-
biography: 'Hello, I am Gijs, I am a Test Engineer for spriteCloud and I like to be lazy and let machines do my work'
|
57
|
-
random-user: # In ./features/support/functions.rb '_RAND-ALPHA_' is replaces for random alphanumeric characters.
|
58
|
-
username: usr_RAND-ALPHA_
|
59
|
-
password: test_RAND_
|
60
|
-
gender: 'Female'
|
61
|
-
experience: 'Ruby,Gherkin'
|
62
|
-
biography: 'Hello, I am a randomized user, today is _TIMESTAMP_ seconds after the existance of computers'
|
45
|
+
functional-testing: /testing/functional-testing/
|
46
|
+
jobs: /jobs
|
47
|
+
training-page: http://training-page.testautomation.info/#
|
@@ -3,9 +3,8 @@
|
|
3
3
|
# Generated by LapisLazuli, version <%= config[:lapis_lazuli][:version] %>
|
4
4
|
# Author: "<%= config[:user] %>" <<%= config[:email] %>>
|
5
5
|
#
|
6
|
-
#
|
7
|
-
# This
|
8
|
-
# Example > Cucumber -t @homepage -p default -p localhost
|
6
|
+
# Cucumber profiles are used to group certain tags and variables
|
7
|
+
# This way you can run specific scenario's on specific environments.
|
9
8
|
|
10
9
|
<%% timestamp = Time.now.strftime("%Y%m%d_%H%M") %>
|
11
10
|
|
@@ -17,19 +16,49 @@ html_report: -f pretty -f html --out=results/<%%=timestamp%>_report.html
|
|
17
16
|
junit_report: -f pretty -f junit --out=results
|
18
17
|
|
19
18
|
################################################################################
|
20
|
-
# Supported browsers (default =
|
19
|
+
# Supported browsers (default = chrome)
|
20
|
+
chrome: BROWSER=chrome
|
21
21
|
ff: BROWSER=firefox
|
22
22
|
firefox: BROWSER=firefox
|
23
|
-
chrome: BROWSER=chrome
|
24
|
-
ie: BROWSER=ie
|
25
|
-
safari: BROWSER=safari
|
26
|
-
edge: BROWSER=edge
|
27
|
-
|
28
23
|
|
29
24
|
################################################################################
|
30
25
|
# Listed environments (default is set in config.yml)
|
31
|
-
t:
|
32
|
-
test: TEST_ENV=test -t @t
|
26
|
+
t: -p test
|
27
|
+
test: TEST_ENV=test -t '@t or @test or @all_env or @all_environments' -t 'not @disabled_on_test'
|
28
|
+
# When you run cucumber -p t
|
29
|
+
# 1. t: -p test > will call profile `test`
|
30
|
+
# 2. TEST_ENV=test > Sets a ruby variable ENV['TEST_ENV'] = 'test'
|
31
|
+
# 3. '@t or @test or @all_env or @all_environments' > Runs all features / scenario's that include either one of these tags
|
32
|
+
# 4. -t 'not @disabled_on_test' > Will not run any feature / scenario that includes this that
|
33
|
+
# A scenario including '@test @disabled_on_test', will be ignored!
|
34
|
+
|
35
|
+
a: -p acceptance
|
36
|
+
acc: -p acceptance
|
37
|
+
accpetance: TEST_ENV=acceptance -t '@a or @acceptance or @all_env or @all_environments' -t 'not @disabled_on_acceptance' -t 'not @disabled_on_acc'
|
38
|
+
|
39
|
+
p: -p production
|
40
|
+
prod: -p production
|
41
|
+
production: TEST_ENV=production -t '@p or @prod or @production or @all_env or @all_environments' -t 'not @disabled_on_production' -t 'not @disabled_on_prod'
|
42
|
+
|
43
|
+
################################################################################
|
44
|
+
# The following is another exmaple of creating (and combining) profiles. In this one we use Version. But it could be anything really.
|
45
|
+
# With version profile you can easily combine a certain environment with a version
|
46
|
+
# An then include (or exclude) certain scenario's that are only available on a specific version.
|
47
|
+
# E.G.: bundle exec cucucumber -p acceptance -p version_14
|
48
|
+
|
49
|
+
v_12: -p version_12
|
50
|
+
version_12: VERSION=12 -t '@v_12 or @ver_12 or @version_12 or @all_versions' -t 'not @disabled_on_ver_12' -t 'not @disabled_on_version_12'
|
51
|
+
|
52
|
+
v_14: -p version_14
|
53
|
+
version_14: VERSION=14 -t '@v_14 or @ver_14 or @version_14 or @all_versions' -t 'not @disabled_on_ver_14' -t 'not @disabled_on_version_14'
|
33
54
|
|
34
|
-
|
35
|
-
|
55
|
+
################################################################################
|
56
|
+
# A few example cucumber commands you could execute:
|
57
|
+
# Run all acceptance tests
|
58
|
+
# bundle exec cucumber -p acc
|
59
|
+
#
|
60
|
+
# Only test a specific scenario on production
|
61
|
+
# bundle exec cucumber -p prod -t @login
|
62
|
+
#
|
63
|
+
# Use the default environment set in config.yml and run a specific tag with extended output
|
64
|
+
# bundle exec cucumber -t @test_24 -x
|
@@ -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,49 @@
|
|
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 - scrolling down
|
15
|
+
Given the user navigates to "home"
|
16
|
+
When the user scrolls down
|
17
|
+
Then text "Project-based services are typically short-term" should display somewhere on the page
|
18
|
+
|
19
|
+
@basic_03
|
20
|
+
Scenario: example03 - Going to a search result
|
21
|
+
Given the user navigates to "https://www.spritecloud.com/?s=lapis+lazuli"
|
22
|
+
When the user scrolls down
|
23
|
+
And the user clicks on link "/announcing-lapislazuli/"
|
24
|
+
Then text "A few days later you are working" should display somewhere on the page
|
25
|
+
|
26
|
+
@basic_04
|
27
|
+
Scenario Outline: example04 - checking multiple pages for the logo
|
28
|
+
Given the user navigates to "<page>"
|
29
|
+
When the user clicks on the spritecloud logo
|
30
|
+
Then the user should be on page "home"
|
31
|
+
Scenarios:
|
32
|
+
| page |
|
33
|
+
| blog |
|
34
|
+
| home |
|
35
|
+
| about-us |
|
36
|
+
| testing |
|
37
|
+
| functional-testing |
|
38
|
+
|
39
|
+
### LEARNING TO DEBUG ###
|
40
|
+
# Scenario' or Feature's including the tag @dev will be ingored when running a regular profile. To run this do:
|
41
|
+
# bundle exec cucumber -t @basic_04 -p debug
|
42
|
+
# or, if you want to test it on a specific environment:
|
43
|
+
# bundle exec cucumber -p production -p debug -t @basic_04
|
44
|
+
# Good luck fixing the problems!
|
45
|
+
@basic_05 @dev
|
46
|
+
Scenario: example_05 - confirming there is a no results page
|
47
|
+
Given the user navigates to "blog"
|
48
|
+
When the user searches for "no_results_expected"
|
49
|
+
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.to_subtype.set(User.get('username'))
|
108
|
+
Auth.password_field.to_subtype.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.html}`"
|
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,102 @@
|
|
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.wait(: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
|
+
#the setter goes too fast sometimes not finishing the username, this will re-set the username when it does
|
56
|
+
browser.wait_until(timeout: 10, message: 'False did not become true withing 10 seconds') {
|
57
|
+
Register.username_field.to_subtype.set(User.get('username'))
|
58
|
+
Register.username_field.value == User.get('username')
|
59
|
+
}
|
60
|
+
Register.username_field.to_subtype.set(User.get('username'))
|
61
|
+
Register.password_field.to_subtype.set(User.get('password'))
|
62
|
+
Register.gender_radio(User.get('gender')).click
|
63
|
+
Register.select_experiences(User.get('experience').split(','))
|
64
|
+
Register.biography_field.to_subtype.set(User.get('biography'))
|
65
|
+
Register.policy_checkbox.to_subtype.set((User.get('complete_all').to_i == 1))
|
66
|
+
end
|
67
|
+
|
68
|
+
def submit_form
|
69
|
+
Register.submit_button.click
|
70
|
+
browser.wait(
|
71
|
+
:like => [:div, :class, 'modal-backdrop fade in'],
|
72
|
+
:condition => :while
|
73
|
+
)
|
74
|
+
end
|
75
|
+
|
76
|
+
def register_user
|
77
|
+
Register.fill_form
|
78
|
+
Register.submit_form
|
79
|
+
end
|
80
|
+
|
81
|
+
def registration_result
|
82
|
+
alert = browser.wait(like: [:div, :class, 'alert'], timeout: 2, throw: false)
|
83
|
+
if alert.nil?
|
84
|
+
return false, 'No message was displayed after registering'
|
85
|
+
elsif !alert.html.include? User.get('username')
|
86
|
+
return false, "An error message did display, but didn't contain the expected text: `#{alert.html}`"
|
87
|
+
end
|
88
|
+
return true, 'Successfully found the success message'
|
89
|
+
end
|
90
|
+
|
91
|
+
def ensure_registered(user)
|
92
|
+
begin
|
93
|
+
Auth.ensure_log_in(user)
|
94
|
+
Auth.log_out
|
95
|
+
rescue Exception => e
|
96
|
+
Register.ensure_open_registrarion
|
97
|
+
Register.register_user
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
end
|