lapis_lazuli 0.9.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -2
  3. data/lapis_lazuli.gemspec +12 -0
  4. data/lib/lapis_lazuli.rb +1 -1
  5. data/lib/lapis_lazuli/api.rb +1 -1
  6. data/lib/lapis_lazuli/argparse.rb +1 -1
  7. data/lib/lapis_lazuli/browser.rb +1 -1
  8. data/lib/lapis_lazuli/browser/error.rb +1 -1
  9. data/lib/lapis_lazuli/browser/find.rb +1 -1
  10. data/lib/lapis_lazuli/browser/interaction.rb +1 -1
  11. data/lib/lapis_lazuli/browser/remote.rb +1 -1
  12. data/lib/lapis_lazuli/browser/screenshots.rb +1 -1
  13. data/lib/lapis_lazuli/browser/wait.rb +23 -12
  14. data/lib/lapis_lazuli/cli.rb +1 -1
  15. data/lib/lapis_lazuli/cucumber.rb +1 -1
  16. data/lib/lapis_lazuli/generators/cucumber.rb +1 -1
  17. data/lib/lapis_lazuli/generators/cucumber/template/Gemfile +3 -7
  18. data/lib/lapis_lazuli/generators/cucumber/template/README.md +3 -1
  19. data/lib/lapis_lazuli/generators/cucumber/template/config/config.yml +32 -2
  20. data/lib/lapis_lazuli/generators/cucumber/template/config/cucumber.yml +0 -9
  21. data/lib/lapis_lazuli/generators/cucumber/template/features/account.feature +26 -0
  22. data/lib/lapis_lazuli/generators/cucumber/template/features/example.feature +23 -10
  23. data/lib/lapis_lazuli/generators/cucumber/template/features/step_definitions/interaction_steps.rb +135 -7
  24. data/lib/lapis_lazuli/generators/cucumber/template/features/step_definitions/precondition_steps.rb +52 -3
  25. data/lib/lapis_lazuli/generators/cucumber/template/features/step_definitions/validation_steps.rb +44 -0
  26. data/lib/lapis_lazuli/generators/cucumber/template/features/support/env.rb +29 -1
  27. data/lib/lapis_lazuli/generators/cucumber/template/features/support/functions.rb +68 -0
  28. data/lib/lapis_lazuli/generic/xpath.rb +1 -1
  29. data/lib/lapis_lazuli/options.rb +1 -1
  30. data/lib/lapis_lazuli/placeholders.rb +1 -1
  31. data/lib/lapis_lazuli/proxy.rb +1 -1
  32. data/lib/lapis_lazuli/runtime.rb +1 -1
  33. data/lib/lapis_lazuli/scenario.rb +1 -1
  34. data/lib/lapis_lazuli/storage.rb +1 -1
  35. data/lib/lapis_lazuli/version.rb +2 -2
  36. data/lib/lapis_lazuli/versions.rb +1 -1
  37. data/lib/lapis_lazuli/world/annotate.rb +1 -1
  38. data/lib/lapis_lazuli/world/api.rb +1 -1
  39. data/lib/lapis_lazuli/world/browser.rb +1 -1
  40. data/lib/lapis_lazuli/world/config.rb +1 -1
  41. data/lib/lapis_lazuli/world/error.rb +1 -1
  42. data/lib/lapis_lazuli/world/hooks.rb +1 -1
  43. data/lib/lapis_lazuli/world/logging.rb +1 -1
  44. data/lib/lapis_lazuli/world/proxy.rb +1 -1
  45. data/lib/lapis_lazuli/world/variable.rb +1 -1
  46. data/test/Gemfile +10 -33
  47. data/test/features/step_definitions/interaction_steps.rb +25 -3
  48. data/test/features/step_definitions/validation_steps.rb +265 -230
  49. data/test/features/timing.feature +40 -4
  50. data/test/server/www/timing.html +15 -0
  51. metadata +90 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 69ecad4834664da669d77a7df4e33aeaf78599f1
4
- data.tar.gz: 8c8c532e1dcf5858a2d6a4e122b77596c50617dd
3
+ metadata.gz: 678920ee3f67c315ee099d4fa4e7d7d30f287265
4
+ data.tar.gz: 74f2220ac07fb93d431ebe44f18d11058c94b9b1
5
5
  SHA512:
6
- metadata.gz: 0feef2515e1dd72ab4d7d815c0776a6feb1f05985eaf49f31fa1feb768c0e7e25f0a73af220b42ac2a50cea84a1beaf6c7f330c90cbb66923a5101f686ec1f96
7
- data.tar.gz: 9957ee6a24b7c780527f6fa48e2f5a855d649c3a29e77aac292a3485bced58f1d0050cba7c22b1c1459d9bc645f4ec9c52280e70a6432bd551f38ce8a1730ce5
6
+ metadata.gz: 84fb25b85cf65cc290b286f2d3aec0c97bb58bd5287844752513d2de52e863821fe4ea58a1cd302c48e29dfb9e2c5db500bd73599a99d4d10a8e1e6dffb8b02e
7
+ data.tar.gz: cc24ed22c6bf41293ebfbc789dc1b36d7f239499c5a53abb6211dfbea378e66778735f654226b968ece874c1f85615c432be226396fcbe9430b2cf48e2cb61dd
data/README.md CHANGED
@@ -17,6 +17,8 @@ such as:
17
17
 
18
18
  ## Installation
19
19
 
20
+ For detailed installation notes, go to: http://www.testautomation.info/Installing_ruby_with_cucumber
21
+
20
22
  Add this line to your application's Gemfile:
21
23
 
22
24
  ```ruby
@@ -67,7 +69,7 @@ name component will be considered the project name, so e.g. a path of
67
69
  Change to that newly created project directory and read the README.md file there
68
70
  for further instructions.
69
71
 
70
- Be sure to read [the Wiki](https://github.com/spriteCloud/lapis-lazuli/wiki) for
72
+ Be sure to read [the GitHub Wiki](https://github.com/spriteCloud/lapis-lazuli/wiki) or [testautomation.info](http://www.testautomation.info/) for
71
73
  further documentation.
72
74
 
73
75
  ## Contributing
@@ -75,4 +77,4 @@ further documentation.
75
77
  Please see [the Wiki page on contributing](https://github.com/spriteCloud/lapis-lazuli/wiki/Contributing)
76
78
 
77
79
  ## License
78
- Copyright (c) 2013-2016 spriteCloud B.V. and other node-apinator contributors. See [the LICENSE file](LICENSE) for details.
80
+ Copyright (c) 2013-2017 spriteCloud B.V. and other node-apinator contributors. See [the LICENSE file](LICENSE) for details.
@@ -23,6 +23,8 @@ Gem::Specification.new do |spec|
23
23
  spec.summary = %q{Cucumber helper functions and scaffolding for easier test automation suite development.}
24
24
  spec.homepage = "https://github.com/spriteCloud/lapis-lazuli"
25
25
  spec.license = "MITNFA"
26
+ spec.required_ruby_version = '~> 2'
27
+ spec.platform = Gem::Platform::RUBY
26
28
 
27
29
  spec.files = `git ls-files -z`.split("\x0")
28
30
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
@@ -42,4 +44,14 @@ Gem::Specification.new do |spec|
42
44
  spec.add_dependency "multi_xml", "~> 0.6"
43
45
  spec.add_dependency "teelogger", "~> 0.5"
44
46
  spec.add_dependency "minitest", "~> 5.10"
47
+ spec.add_dependency "ffi", "~> 1.9"
48
+ spec.add_dependency "rspec", "~> 3.5"
49
+
50
+ # webdriver specifics
51
+ spec.add_dependency "selenium-webdriver", "~> 3"
52
+ spec.add_dependency "watir", "~> 6"
53
+ spec.add_dependency "cucumber", "~> 2"
54
+
55
+ # Debugging tool
56
+ spec.add_dependency "byebug", "~> 9"
45
57
  end
@@ -2,7 +2,7 @@
2
2
  # LapisLazuli
3
3
  # https://github.com/spriteCloud/lapis-lazuli
4
4
  #
5
- # Copyright (c) 2013-2016 spriteCloud B.V. and other LapisLazuli contributors.
5
+ # Copyright (c) 2013-2017 spriteCloud B.V. and other LapisLazuli contributors.
6
6
  # All rights reserved.
7
7
  #
8
8
 
@@ -2,7 +2,7 @@
2
2
  # LapisLazuli
3
3
  # https://github.com/spriteCloud/lapis-lazuli
4
4
  #
5
- # Copyright (c) 2013-2016 spriteCloud B.V. and other LapisLazuli contributors.
5
+ # Copyright (c) 2013-2017 spriteCloud B.V. and other LapisLazuli contributors.
6
6
  # All rights reserved.
7
7
  #
8
8
 
@@ -2,7 +2,7 @@
2
2
  # LapisLazuli
3
3
  # https://github.com/spriteCloud/lapis-lazuli
4
4
  #
5
- # Copyright (c) 2013-2016 spriteCloud B.V. and other LapisLazuli contributors.
5
+ # Copyright (c) 2013-2017 spriteCloud B.V. and other LapisLazuli contributors.
6
6
  # All rights reserved.
7
7
  #
8
8
 
@@ -2,7 +2,7 @@
2
2
  # LapisLazuli
3
3
  # https://github.com/spriteCloud/lapis-lazuli
4
4
  #
5
- # Copyright (c) 2013-2016 spriteCloud B.V. and other LapisLazuli contributors.
5
+ # Copyright (c) 2013-2017 spriteCloud B.V. and other LapisLazuli contributors.
6
6
  # All rights reserved.
7
7
  #
8
8
 
@@ -2,7 +2,7 @@
2
2
  # LapisLazuli
3
3
  # https://github.com/spriteCloud/lapis-lazuli
4
4
  #
5
- # Copyright (c) 2013-2016 spriteCloud B.V. and other LapisLazuli contributors.
5
+ # Copyright (c) 2013-2017 spriteCloud B.V. and other LapisLazuli contributors.
6
6
  # All rights reserved.
7
7
  #
8
8
 
@@ -2,7 +2,7 @@
2
2
  # LapisLazuli
3
3
  # https://github.com/spriteCloud/lapis-lazuli
4
4
  #
5
- # Copyright (c) 2013-2016 spriteCloud B.V. and other LapisLazuli contributors.
5
+ # Copyright (c) 2013-2017 spriteCloud B.V. and other LapisLazuli contributors.
6
6
  # All rights reserved.
7
7
  #
8
8
 
@@ -2,7 +2,7 @@
2
2
  # LapisLazuli
3
3
  # https://github.com/spriteCloud/lapis-lazuli
4
4
  #
5
- # Copyright (c) 2013-2016 spriteCloud B.V. and other LapisLazuli contributors.
5
+ # Copyright (c) 2013-2017 spriteCloud B.V. and other LapisLazuli contributors.
6
6
  # All rights reserved.
7
7
  #
8
8
 
@@ -2,7 +2,7 @@
2
2
  # LapisLazuli
3
3
  # https://github.com/spriteCloud/lapis-lazuli
4
4
  #
5
- # Copyright (c) 2013-2016 spriteCloud B.V. and other LapisLazuli contributors.
5
+ # Copyright (c) 2013-2017 spriteCloud B.V. and other LapisLazuli contributors.
6
6
  # All rights reserved.
7
7
  #
8
8
 
@@ -2,7 +2,7 @@
2
2
  # LapisLazuli
3
3
  # https://github.com/spriteCloud/lapis-lazuli
4
4
  #
5
- # Copyright (c) 2013-2016 spriteCloud B.V. and other LapisLazuli contributors.
5
+ # Copyright (c) 2013-2017 spriteCloud B.V. and other LapisLazuli contributors.
6
6
  # All rights reserved.
7
7
  #
8
8
 
@@ -2,7 +2,7 @@
2
2
  # LapisLazuli
3
3
  # https://github.com/spriteCloud/lapis-lazuli
4
4
  #
5
- # Copyright (c) 2013-2016 spriteCloud B.V. and other LapisLazuli contributors.
5
+ # Copyright (c) 2013-2017 spriteCloud B.V. and other LapisLazuli contributors.
6
6
  # All rights reserved.
7
7
  #
8
8
 
@@ -59,11 +59,14 @@ module BrowserModule
59
59
  condition = options[:condition]
60
60
  options.delete(:condition)
61
61
 
62
- # The easiest way to deal with find's new :throw policy is to set it to
63
- # false.
64
- options[:throw] = false
62
+ # Removing context from the options to preven an error in Marshal.dump
63
+ context = options[:selectors][0][:context]
64
+ options[:selectors][0].delete(:context)
65
65
 
66
- # pp "got options: #{options}"
66
+ # The easiest way to deal with find's new :throw policy is to set it to false.
67
+ # We'll store the original value in a variable to catch it later.
68
+ throw = options[:throw]
69
+ options[:throw] = false
67
70
 
68
71
  # The proc we're waiting for invokes the find_func
69
72
  results = []
@@ -74,7 +77,10 @@ module BrowserModule
74
77
  retries.times do
75
78
  begin
76
79
  opts = Marshal.load(Marshal.dump(options))
80
+ # Putting :context back in the selector if it was used
81
+ opts[:selectors][0][:context] = context unless context.nil?
77
82
  results = send(find_func.to_sym, opts)
83
+
78
84
  if results.respond_to? :length
79
85
  res = (results.length > 0)
80
86
  else
@@ -104,16 +110,21 @@ module BrowserModule
104
110
  res = Watir::Wait.send(condition, timeout: timeout, &find_proc)
105
111
  rescue Watir::Wait::TimeoutError => e
106
112
  world.log.debug("Caught timeout: #{e}")
107
- err = e
113
+ begin
114
+ # Catch the default error and add the selectors to it.
115
+ unless throw === false
116
+ # Only raise an error if :throw is not false
117
+ raise "#{e.message} with selectors: #{options[:selectors]}"
118
+ end
119
+ rescue RuntimeError => err
120
+ options[:exception] = err
121
+ options[:message] = optional_message('Error in wait', options)
122
+ world.error(options)
123
+ end
108
124
  end
109
125
 
110
126
  # Filter out any nil results
111
127
  filter_results = results.select {|i| not i.nil?}
112
- # Error handling
113
- if not err.nil?
114
- options[:exception] = err
115
- world.error(options)
116
- end
117
128
 
118
129
  # Set if the underlying find function returns single results
119
130
  if has_single
@@ -132,6 +143,7 @@ module BrowserModule
132
143
  :stale_retries => 3,
133
144
  :condition => :until,
134
145
  :screenshot => false,
146
+ :throw => true
135
147
  }
136
148
  options = ERROR_OPTIONS.merge options
137
149
  options = parse_args(options, :selectors, *args)
@@ -150,7 +162,6 @@ module BrowserModule
150
162
  sel[:filter_by] = :present?
151
163
  end
152
164
  end
153
-
154
165
  return options
155
166
  end
156
167
  end # module Wait
@@ -2,7 +2,7 @@
2
2
  # LapisLazuli
3
3
  # https://github.com/spriteCloud/lapis-lazuli
4
4
  #
5
- # Copyright (c) 2013-2016 spriteCloud B.V. and other LapisLazuli contributors.
5
+ # Copyright (c) 2013-2017 spriteCloud B.V. and other LapisLazuli contributors.
6
6
  # All rights reserved.
7
7
  #
8
8
  require 'thor'
@@ -2,7 +2,7 @@
2
2
  # LapisLazuli
3
3
  # https://github.com/spriteCloud/lapis-lazuli
4
4
  #
5
- # Copyright (c) 2013-2016 spriteCloud B.V. and other LapisLazuli contributors.
5
+ # Copyright (c) 2013-2017 spriteCloud B.V. and other LapisLazuli contributors.
6
6
  # All rights reserved.
7
7
  #
8
8
 
@@ -2,7 +2,7 @@
2
2
  # LapisLazuli
3
3
  # https://github.com/spriteCloud/lapis-lazuli
4
4
  #
5
- # Copyright (c) 2013-2016 spriteCloud B.V. and other LapisLazuli contributors.
5
+ # Copyright (c) 2013-2017 spriteCloud B.V. and other LapisLazuli contributors.
6
6
  # All rights reserved.
7
7
  #
8
8
 
@@ -1,12 +1,8 @@
1
1
  source 'http://rubygems.org'
2
2
 
3
- # Add following two lines to your ~/.gemrc or /etc/gemrc:
4
- # install: --no-rdoc --no-ri
5
- # update: --no-rdoc --no-ri
6
-
7
- # Install all the webdriver gems and cucumber
8
- gem 'watir'
9
- gem 'cucumber'
3
+ # Run your project as following
4
+ # > bundle install
5
+ # > bundle exec cucumber
10
6
 
11
7
  # LapisLazul itself
12
8
  gem 'lapis_lazuli', <%= config[:lapis_lazuli][:dependency] %>
@@ -6,8 +6,10 @@ Author: "<%= config[:user] %>" <<%= config[:email] %>>
6
6
 
7
7
  ## General
8
8
 
9
- - Make sure you have ruby 1.9 or later installed.
9
+ - Make sure you have ruby 2.0 or later installed.
10
10
  - Make sure you have firefox and/or chrome installed
11
+ - Download chromedriver and put it into your ./ruby/bin folder
12
+ - Download geckodriver and put it into your ./ruby/bin folder
11
13
  - Install the bundler gem:
12
14
 
13
15
  $ gem install bundler
@@ -21,9 +21,39 @@ error_strings:
21
21
  ################################################################################
22
22
  # Environment specific variables
23
23
  test:
24
+ pages:
25
+ root: http://username:password@test.spritecloud.com #Not an existing page, note the username/password user inside the URL
26
+ home: /
27
+ about-us: /about-us/
24
28
 
25
29
  uat:
30
+ pages:
31
+ root: http://username:password@uat.spritecloud.com #Not an existing page, note the username/password user inside the URL
32
+ home: /
33
+ about-us: /about-us/
26
34
 
27
35
  production:
28
- google:
29
- english: http://www.google.com/ncr
36
+ pages:
37
+ root: https://spritecloud.com
38
+ home: /
39
+ about-us: /about-us/
40
+ testing: /testing/
41
+ blog: /blog/
42
+ functional-testing: /testing/functional/
43
+ training-page: http://training-page.testautomation.info
44
+
45
+
46
+ # Different user variables
47
+ users:
48
+ default-user: # These are the default variable settings. If no setting was specified, these values will be used.
49
+ username: test
50
+ password: test
51
+ gender: 'Male'
52
+ experience: 'Ruby,Cucumber,HTML,XPath'
53
+ biography: 'Hello, I am Gijs, I am a Test Engineer for spriteCloud and I like to be lazy and let machines do my work'
54
+ random-user: # In ./features/support/functions.rb '_RAND-ALPHA_' is replaces for random alphanumeric characters.
55
+ username: usr_RAND-ALPHA_
56
+ password: test_RAND_
57
+ gender: 'Female'
58
+ experience: 'Ruby,Gherkin'
59
+ biography: 'Hello, I am a randomized user, today is _TIMESTAMP_ seconds after the existance of computers'
@@ -1,13 +1,4 @@
1
- ################################################################################
2
- # Copyright <%= config[:year] %> spriteCloud B.V. All rights reserved.
3
- # Generated by LapisLazuli, version <%= config[:lapis_lazuli][:version] %>
4
- # Author: "<%= config[:user] %>" <<%= config[:email] %>>
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
9
1
 
10
- <%% timestamp = Time.now.strftime("%Y%m%d_%H%M") %>
11
2
 
12
3
  ################################################################################
13
4
  # Type of testrun
@@ -0,0 +1,26 @@
1
+ @account
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
+ @account01 @log_in #@pause # You can add @pause to have a break between every step.
11
+ Scenario: account01 - Logging in
12
+ Given the user is logged out
13
+ When "default-user" logs in
14
+ Then the page should display as logged in state
15
+
16
+ @account02 @log_out
17
+ Scenario: account01 - Logging out
18
+ Given "default-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
+ @account03 @registration
23
+ Scenario: account03 - Registation
24
+ Given the user is logged out
25
+ When "random-user" registers for a new account
26
+ Then the page should display as logged in state
@@ -4,14 +4,27 @@ When I want to learn how to make test cases
4
4
  As a user of the test automation tool
5
5
  I want to run and adjust the tests below
6
6
 
7
- @example01
8
- Scenario: example01 - Google Search
9
- Given the user navigates to Google in english
10
- When the user searches for "spriteCloud"
11
- Then text "www.spriteCloud.com" should display
7
+ @example01
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
12
12
 
13
- @example02
14
- Scenario: example02 - Going to a search result
15
- Given the user has searched for "spriteCloud" on Google in english
16
- When the user clicks on link "spritecloud.com"
17
- Then text "Test your software, not your reputation" should display
13
+ @example02
14
+ Scenario: example02 - Going to a search result
15
+ Given the user has searched for "lapis lazuli" on "blog"
16
+ When the user clicks on link "/announcing-lapislazuli/"
17
+ Then text "Let's talk about testing" should display
18
+
19
+ @example03
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 |
@@ -5,18 +5,29 @@
5
5
 
6
6
  # interactions_steps.rb is used to interact with elements on the page.
7
7
 
8
- Given(/^the user navigates to (.*?) in (.*?)$/) do |site, language|
9
- # Combine the configuration depth with dots
10
- config_name = "#{site.downcase}.#{language.downcase}"
8
+ Given(/^the user navigates to "(.*?)"$/) do |page|
11
9
  # Get the value of the configuration (see /config/config.yml)
12
- url = env(config_name)
10
+
11
+ # First grab the root URL defined in the config
12
+ url = env('pages.root')
13
+ # Then add the page specific part to the URL
14
+ url += env("pages.#{page}")
15
+
16
+ # Go to the URL
17
+ browser.goto url
18
+ end
19
+
20
+ Given(/^the user navigates to the "(.*?)" page$/) do |page|
21
+ # Get the value of the configuration (see /config/config.yml)
22
+ url = env("#{page}")
23
+
13
24
  # Go to the URL
14
25
  browser.goto url
15
26
  end
16
27
 
17
28
  Given(/^the user searches for "(.*?)"$/) do |query|
18
29
  # Get the input element
19
- searchbox = browser.find(:text_field => {:name => "q"})
30
+ searchbox = browser.find(:text_field => {:name => "s"})
20
31
  # Make sure the input field is empty
21
32
  searchbox.clear rescue log.debug "Could not clear searchbox"
22
33
  # Fill in the query
@@ -29,9 +40,126 @@ When(/^the user clicks on link "(.*?)"$/) do |url|
29
40
  # Search for the element that includes the expected text
30
41
  browser.wait(
31
42
  :like => {
32
- :element => :a,
43
+ :element => :a,
33
44
  :attribute => :href,
34
- :include => url
45
+ :include => url
35
46
  }
36
47
  ).click
48
+ end
49
+
50
+ When(/^the user clicks on the spritecloud logo$/) do
51
+ # Search for the logo
52
+ logo = browser.find(
53
+ :like => [:img, :id, 'logo'],
54
+ :message => 'Unable to find the logo on this page.'
55
+ )
56
+ # And click the logo
57
+ logo.click
58
+ end
59
+
60
+ # A step definition is a regex, to learn more about this go to http://rubular.com/
61
+ # The following step definition accepts both:
62
+ # - the user logs in > will use the last stored user data
63
+ # - "user-x" logs in > will load user data from config.yml
64
+ When(/^"?(.*?|the user)"? logs in$/) do |user_tag|
65
+ if user_tag != 'the user'
66
+ # Set the user data
67
+ set_user_data(user_tag)
68
+ end
69
+ # Fill in the user form
70
+ browser.find(
71
+ :like => [:input, :id, 'login-username']
72
+ ).set(get_user_data('username'))
73
+ browser.find(
74
+ :like => [:input, :id, 'login-password']
75
+ ).set(get_user_data('password'))
76
+
77
+ # Press the submit button
78
+ browser.find(
79
+ :like => [:button, :id, 'button-login']
80
+ ).click
81
+ end
82
+
83
+ When(/^the user clicks on the logout button$/) do
84
+ # pending # This is an example
85
+
86
+ # First get the header to use as a context for the logout button
87
+ header = browser.wait(:like => [:nav, :class, 'navbar-fixed-top'])
88
+
89
+ # Then click the logout button (in this case, first a drop down needs to be clicked, before the logout button shows)
90
+ browser.find(
91
+ :like => [:a, :id, 'user_dropdown'],
92
+ :context => header,
93
+ :message => 'Unable to click on the user icon'
94
+ ).click
95
+ dropdown = browser.wait(
96
+ :like => [:ul, :class, 'dropdown-menu'],
97
+ :timeout => 5,
98
+ :message => 'The user dropdown didn`t become present.'
99
+ )
100
+ browser.find(
101
+ :like => [:a, :id, 'link-logout'],
102
+ :context => dropdown,
103
+ :error => 'Failed to click the logout button.'
104
+ ).click
105
+ end
106
+
107
+ When(/^"(.*?)" registers for a new account$/) do |user_tag|
108
+ # pending # Write code here that turns the phrase above into concrete actions
109
+
110
+ # Set the user data
111
+ set_user_data(user_tag)
112
+
113
+ # Go to the registration page
114
+ step 'the user navigates to the "training-page" page'
115
+ browser.find(:like => [:button, :id, 'button-register']).click
116
+
117
+ # Fill in the form
118
+
119
+ # Get the form container and use it as a context to find the fields
120
+ form = browser.wait(:like => [:form, :id, 'form-register'])
121
+
122
+ # Fill in the details
123
+ browser.find(:element => {:name => 'username'}, :context => form).set get_user_data('username')
124
+ browser.find(:element => {:name => 'password'}, :context => form).set get_user_data('password')
125
+
126
+ # Select gender
127
+ browser.find(
128
+ :label => {:text => /#{get_user_data('gender')}/i},
129
+ :context => form,
130
+ :message => "Unable to find gender `#{get_user_data('gender')}`, are you sure it's an option to select??"
131
+ ).click
132
+
133
+ # Select experiences from the multi-select list
134
+ multi_selector = browser.find(:like => [:select, :id, "register-experience"], :context => form)
135
+ experiences = get_user_data('experience')
136
+ # Experiences is a list of words comma separated, EG `Ruby,Cucumber,Watir`
137
+ # The following function will cut text at every comma, and loop trough every separate word
138
+ experiences.split(',').each do |exp|
139
+ option = browser.find(
140
+ :option => {:value => /#{exp}/i},
141
+ :context => multi_selector
142
+ )
143
+ option.click
144
+ end
145
+
146
+ # Fill in the biagraphy
147
+ browser.find(
148
+ :like => [:textarea, :id, 'register-bio']
149
+ ).send_keys(get_user_data('biography'))
150
+
151
+ # Click the accept policy checkbox
152
+ browser.find(:like => [:input, :id, 'register-complete-all']).click
153
+
154
+ # Press the submit button
155
+ browser.find(:button => {:id => 'button-save'}).click
156
+
157
+ # Wait for the success message to display
158
+ browser.wait(
159
+ :like => [:div, :class, 'alert-success'],
160
+ :message => 'The successfully registered message did not display.'
161
+ )
162
+
163
+ # The website we're testing on, doesn't log in the user automatically. So let's trigger that step manually
164
+ step 'the user logs in'
37
165
  end