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.
Files changed (54) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +1 -1
  3. data/lapis_lazuli.gemspec +10 -8
  4. data/lib/lapis_lazuli/api.rb +1 -1
  5. data/lib/lapis_lazuli/argparse.rb +1 -1
  6. data/lib/lapis_lazuli/browser.rb +37 -61
  7. data/lib/lapis_lazuli/browser/error.rb +89 -62
  8. data/lib/lapis_lazuli/browser/find.rb +1 -2
  9. data/lib/lapis_lazuli/cli.rb +1 -1
  10. data/lib/lapis_lazuli/cucumber.rb +1 -1
  11. data/lib/lapis_lazuli/generators/cucumber.rb +1 -1
  12. data/lib/lapis_lazuli/generators/cucumber/template/README.md +2 -0
  13. data/lib/lapis_lazuli/generators/cucumber/template/config/config.yml +6 -21
  14. data/lib/lapis_lazuli/generators/cucumber/template/config/cucumber.yml +42 -13
  15. data/lib/lapis_lazuli/generators/cucumber/template/config/users.yml +21 -0
  16. data/lib/lapis_lazuli/generators/cucumber/template/features/1_basic.feature +49 -0
  17. data/lib/lapis_lazuli/generators/cucumber/template/features/2_account.feature +38 -0
  18. data/lib/lapis_lazuli/generators/cucumber/template/features/3_todo_list.feature +23 -0
  19. data/lib/lapis_lazuli/generators/cucumber/template/features/helpers/authentication_helper.rb +122 -0
  20. data/lib/lapis_lazuli/generators/cucumber/template/features/helpers/navigation_helper.rb +64 -0
  21. data/lib/lapis_lazuli/generators/cucumber/template/features/helpers/registration_helper.rb +102 -0
  22. data/lib/lapis_lazuli/generators/cucumber/template/features/helpers/user_helper.rb +74 -0
  23. data/lib/lapis_lazuli/generators/cucumber/template/features/step_definitions/account_steps.rb +60 -0
  24. data/lib/lapis_lazuli/generators/cucumber/template/features/step_definitions/basic_steps.rb +70 -0
  25. data/lib/lapis_lazuli/generators/cucumber/template/features/step_definitions/todo_steps.rb +27 -0
  26. data/lib/lapis_lazuli/generators/cucumber/template/features/support/env.rb +3 -2
  27. data/lib/lapis_lazuli/generic/xpath.rb +1 -1
  28. data/lib/lapis_lazuli/options.rb +3 -2
  29. data/lib/lapis_lazuli/placeholders.rb +1 -1
  30. data/lib/lapis_lazuli/proxy.rb +1 -1
  31. data/lib/lapis_lazuli/runtime.rb +1 -1
  32. data/lib/lapis_lazuli/scenario.rb +1 -1
  33. data/lib/lapis_lazuli/storage.rb +1 -1
  34. data/lib/lapis_lazuli/version.rb +2 -2
  35. data/lib/lapis_lazuli/versions.rb +1 -1
  36. data/lib/lapis_lazuli/world/config.rb +348 -334
  37. data/lib/lapis_lazuli/world/hooks.rb +85 -84
  38. data/lib/lapis_lazuli/world/logging.rb +1 -1
  39. data/test/Gemfile +2 -16
  40. data/test/config/config.yml +7 -6
  41. data/test/config/cucumber.yml +6 -8
  42. data/test/features/bindings.feature +1 -1
  43. data/test/features/browser.feature +1 -1
  44. data/test/features/step_definitions/interaction_steps.rb +5 -2
  45. data/test/features/step_definitions/validation_steps.rb +2 -2
  46. data/test/features/support/env.rb +21 -1
  47. data/test/results/latest_results.json +0 -0
  48. metadata +74 -28
  49. data/lib/lapis_lazuli/generators/cucumber/template/features/account.feature +0 -26
  50. data/lib/lapis_lazuli/generators/cucumber/template/features/example.feature +0 -30
  51. data/lib/lapis_lazuli/generators/cucumber/template/features/step_definitions/interaction_steps.rb +0 -165
  52. data/lib/lapis_lazuli/generators/cucumber/template/features/step_definitions/precondition_steps.rb +0 -63
  53. data/lib/lapis_lazuli/generators/cucumber/template/features/step_definitions/validation_steps.rb +0 -67
  54. 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
- training-page: http://training-page.testautomation.info
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
- # Ask developer of testsuite to add profiles where desired.
7
- # This file defines predefined profiles that can be used.
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 = firefox)
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: TEST_ENV=test -t @t,@test
32
- test: TEST_ENV=test -t @t,@test
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
- p: TEST_ENV=production -t @p,@prod
35
- production: TEST_ENV=production -t @p,@prod
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