lapis_lazuli 2.0.1 → 2.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/lapis_lazuli.gemspec +3 -2
  3. data/lib/lapis_lazuli/browser.rb +36 -60
  4. data/lib/lapis_lazuli/browser/error.rb +89 -62
  5. data/lib/lapis_lazuli/generators/cucumber/template/README.md +2 -0
  6. data/lib/lapis_lazuli/generators/cucumber/template/config/config.yml +5 -20
  7. data/lib/lapis_lazuli/generators/cucumber/template/config/cucumber.yml +42 -13
  8. data/lib/lapis_lazuli/generators/cucumber/template/config/users.yml +21 -0
  9. data/lib/lapis_lazuli/generators/cucumber/template/features/1_basic.feature +42 -0
  10. data/lib/lapis_lazuli/generators/cucumber/template/features/2_account.feature +38 -0
  11. data/lib/lapis_lazuli/generators/cucumber/template/features/3_todo_list.feature +23 -0
  12. data/lib/lapis_lazuli/generators/cucumber/template/features/helpers/authentication_helper.rb +122 -0
  13. data/lib/lapis_lazuli/generators/cucumber/template/features/helpers/navigation_helper.rb +64 -0
  14. data/lib/lapis_lazuli/generators/cucumber/template/features/helpers/registration_helper.rb +93 -0
  15. data/lib/lapis_lazuli/generators/cucumber/template/features/helpers/user_helper.rb +74 -0
  16. data/lib/lapis_lazuli/generators/cucumber/template/features/step_definitions/account_steps.rb +60 -0
  17. data/lib/lapis_lazuli/generators/cucumber/template/features/step_definitions/basic_steps.rb +65 -0
  18. data/lib/lapis_lazuli/generators/cucumber/template/features/step_definitions/todo_steps.rb +27 -0
  19. data/lib/lapis_lazuli/generators/cucumber/template/features/support/env.rb +3 -2
  20. data/lib/lapis_lazuli/options.rb +2 -1
  21. data/lib/lapis_lazuli/version.rb +1 -1
  22. data/lib/lapis_lazuli/world/config.rb +348 -334
  23. data/lib/lapis_lazuli/world/hooks.rb +85 -84
  24. data/lib/lapis_lazuli/world/logging.rb +1 -1
  25. data/test/config/config.yml +7 -6
  26. data/test/config/cucumber.yml +6 -8
  27. data/test/features/bindings.feature +1 -1
  28. data/test/features/browser.feature +1 -1
  29. data/test/features/step_definitions/interaction_steps.rb +5 -2
  30. data/test/features/step_definitions/validation_steps.rb +2 -2
  31. data/test/features/support/env.rb +22 -1
  32. data/test/results/latest_results.json +0 -0
  33. metadata +49 -16
  34. data/lib/lapis_lazuli/generators/cucumber/template/features/account.feature +0 -26
  35. data/lib/lapis_lazuli/generators/cucumber/template/features/example.feature +0 -30
  36. data/lib/lapis_lazuli/generators/cucumber/template/features/step_definitions/interaction_steps.rb +0 -165
  37. data/lib/lapis_lazuli/generators/cucumber/template/features/step_definitions/precondition_steps.rb +0 -63
  38. data/lib/lapis_lazuli/generators/cucumber/template/features/step_definitions/validation_steps.rb +0 -67
  39. data/lib/lapis_lazuli/generators/cucumber/template/features/support/functions.rb +0 -68
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5ba7d3bc93d8cc88cf24da242e8ce8d9fac690e1
4
- data.tar.gz: 547f0135054b8d4751a01df27842e9d1d679959e
3
+ metadata.gz: dd19104d77095323efb21cf19b64cde8bec5100c
4
+ data.tar.gz: 89abab95df6c9a75671920c8eb47b3dcaf162434
5
5
  SHA512:
6
- metadata.gz: d7b214da9b4862efb132d7aa529bb69cd46c7bcc6af194c95d8eff6a2bb0900eaea16206f28a128fa8cc23e71f5040512e22ec91f5bde2d999a199610eec37c1
7
- data.tar.gz: 4ecc7e7c7512f976240242843ae9666c1bcba998ad3afc9b1b591e5c85abbb89c238e609d1ef0a3f5da107c4b91ac8dfee87cd590c12d751a457e966708c705c
6
+ metadata.gz: 48c857eeb8aa16f4b6ed92b288aa01a96e61644c12cbfa3aa3f1c1fc7f14f710eaa58267837bb141ca45f2eed9dfa65228f1beb85881de8b0314f7eda78da162
7
+ data.tar.gz: ecb34119aec8dcec4a038df15a824fac4f75e7ceee5596aa97b2da0cfb37b7c30d531e2b8498bf120da565fc614c484da8ac6268a19cf929a4c8e7be53048fb2
@@ -42,10 +42,11 @@ Gem::Specification.new do |spec|
42
42
  spec.add_dependency "minitest", "~> 5.10"
43
43
  spec.add_dependency "thor", "~> 0.19" # Used in the cucumber project generator
44
44
  spec.add_dependency "facets", "~> 3.1" # Used in the cucumber project generator
45
+ spec.add_dependency "deep_merge", "~> 1.2"
45
46
 
46
47
  # webdriver specifics
47
- spec.add_dependency "selenium-webdriver", "~> 3"
48
+ spec.add_dependency "selenium-webdriver", ">= 2.0", '< 4'
48
49
  spec.add_dependency "watir", "~> 6"
49
- spec.add_dependency "cucumber", "~> 2"
50
+ spec.add_dependency "cucumber", ">= 2.0", '< 4.0'
50
51
 
51
52
  end
@@ -124,7 +124,7 @@ module LapisLazuli
124
124
  # Add this browser to the list of all browsers
125
125
  LapisLazuli::Browser.add_browser(self)
126
126
  # Making sure all browsers are gracefully closed when the exit event is triggered.
127
- at_exit { LapisLazuli::Browser::close_all 'exit event trigger' }
127
+ at_exit {LapisLazuli::Browser::close_all 'exit event trigger'}
128
128
  end
129
129
  end
130
130
 
@@ -250,10 +250,10 @@ module LapisLazuli
250
250
  if @@cached_browser_options.has_key?(:device)
251
251
  optional_data[:device] = @@cached_browser_options[:device]
252
252
  # Check if the ENV['DEVICE'] variable is set
253
- elsif !world.env_or_config('DEVICE').nil?
253
+ elsif world.env_or_config('DEVICE', false)
254
254
  optional_data[:device] = world.env_or_config('DEVICE')
255
255
  # Else grab the default set device
256
- elsif !world.env_or_config('default_device').nil?
256
+ elsif world.env_or_config('default_device', false)
257
257
  optional_data[:device] = world.env_or_config('default_device')
258
258
  else
259
259
  warn 'No default device, nor a selected device was set. Browser default settings will be loaded. More info: http://testautomation.info/Lapis_Lazuli:Device_Simulation'
@@ -307,70 +307,46 @@ module LapisLazuli
307
307
  raise LoadError, "#{err}: you need to add 'watir' to your Gemfile before using the browser."
308
308
  end
309
309
 
310
- # No browser? Does the config have a browser? Default to firefox
310
+ # No browser? Does the config have a browser?
311
311
  if browser_wanted.nil?
312
- browser_wanted = world.env_or_config('browser', 'firefox')
312
+ browser_wanted = world.env_or_config('browser', nil)
313
313
  end
314
314
 
315
- # Select the correct browser
316
- case browser_wanted.to_s.downcase
317
- when 'chrome'
318
- b = :chrome
319
- when 'edge'
320
- b = :edge
321
- when 'safari'
322
- b = :safari
323
- when 'ie'
324
- require 'rbconfig'
325
- if (RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/)
326
- b = :ie
327
- else
328
- world.error("You can't run IE tests on non-Windows machine")
329
- end
330
- when 'ios'
331
- if RUBY_PLATFORM.downcase.include?("darwin")
332
- b = :iphone
333
- else
334
- world.error("You can't run IOS tests on non-mac machine")
335
- end
336
- when 'remote'
337
- b = :remote
338
- else
339
- b = :firefox
340
- end
315
+ b = browser_wanted
316
+ b = b.to_sym unless b.nil?
341
317
 
342
318
  # Overwrite user-agent if a device simulation is set and it contains a user-agent
343
319
  if !device_configuration.nil? and !device_configuration['user-agent'].nil?
344
- case b
345
- when :firefox
346
- # Create a firefox profile if it does not exist yet
347
- if optional_data[:profile].nil?
348
- optional_data[:profile] = Selenium::WebDriver::Firefox::Profile.new
349
- else
350
- # If the profile already exists, we need to create a duplicate, so we don't overwrite any settings.
351
- optional_data[:profile] = optional_data[:profile].dup
352
- end
353
- # Add the user agent to it if it has not been set yet
354
- if optional_data[:profile].instance_variable_get(:@additional_prefs)['general.useragent.override'].nil?
355
- optional_data[:profile]['general.useragent.override'] = device_configuration['user-agent']
356
- else
357
- world.log.debug "User-agent was already set in the :profile."
358
- end
359
- when :chrome
360
- ua_string = "--user-agent=#{device_configuration['user-agent']}"
361
- if optional_data[:switches].nil?
362
- optional_data[:switches] = [ua_string]
363
- elsif !optional_data[:switches].join(',').include? '--user-agent='
364
- optional_data[:switches].push ua_string
365
- else
366
- world.log.debug "User-agent was already set in the :switches."
367
- end
368
- else
369
- warn "#{device} user agent cannot be set for #{b.to_s}. Only Chrome & Firefox are supported."
320
+ # Firefox user-agent settings
321
+ # Create a firefox profile if it does not exist yet
322
+ if optional_data[:profile].nil?
323
+ optional_data[:profile] = Selenium::WebDriver::Firefox::Profile.new
324
+ else
325
+ # If the profile already exists, we need to create a duplicate, so we don't overwrite any settings.
326
+ optional_data[:profile] = optional_data[:profile].dup
327
+ end
328
+ # Add the user agent to it if it has not been set yet
329
+ if optional_data[:profile].instance_variable_get(:@additional_prefs)['general.useragent.override'].nil?
330
+ optional_data[:profile]['general.useragent.override'] = device_configuration['user-agent']
331
+ else
332
+ world.log.debug "User-agent was already set in the :profile."
333
+ end
334
+ # Chrome user-agent settings
335
+ ua_string = "--user-agent=#{device_configuration['user-agent']}"
336
+ if optional_data[:switches].nil?
337
+ optional_data[:switches] = [ua_string]
338
+ elsif !optional_data[:switches].join(',').include? '--user-agent='
339
+ optional_data[:switches].push ua_string
340
+ else
341
+ world.log.debug "User-agent was already set in the :switches."
342
+ end
343
+ if b != :firefox and b != :chrome
344
+ warn "#{device} user agent cannot be set for #{b.to_s}. Only Chrome & Firefox are supported."
370
345
  end
371
346
  end
372
347
 
373
- args = [b]
348
+ args = []
349
+ args = [b] unless b.nil?
374
350
  @browser_name = b.to_s
375
351
  if b == :remote
376
352
  # Get the config
@@ -380,12 +356,12 @@ module LapisLazuli
380
356
  remote_settings = {}
381
357
 
382
358
  # Add the config to the settings using downcase string keys
383
- remote_config.each { |k, v| remote_settings[k.to_s.downcase] = v }
359
+ remote_config.each {|k, v| remote_settings[k.to_s.downcase] = v}
384
360
 
385
361
  if optional_data.is_a? Hash
386
362
  # Convert the optional data to downcase string keys
387
363
  string_hash = Hash.new
388
- optional_data.each { |k, v| string_hash[k.to_s.downcase] = v }
364
+ optional_data.each {|k, v| string_hash[k.to_s.downcase] = v}
389
365
 
390
366
  # Merge them with the settings
391
367
  remote_settings.merge! string_hash
@@ -7,87 +7,114 @@
7
7
  #
8
8
 
9
9
  module LapisLazuli
10
- module BrowserModule
10
+ module BrowserModule
11
11
 
12
- ##
13
- # Module with error handling related functionality (World)
14
- module Error
15
12
  ##
16
- # Does this page have errors?
17
- # Checks the pagetext for error_strings that are specified in the config
18
- def has_error?
19
- errors = self.get_html_errors
20
- js_errors = self.get_js_errors
21
- if not js_errors.nil?
22
- errors += js_errors
23
- end
13
+ # Module with error handling related functionality (World)
14
+ module Error
15
+ ##
16
+ # Does this page have errors?
17
+ # Checks the pagetext for error_strings that are specified in the config
18
+ def has_error?
19
+ errors = self.get_html_errors
20
+ js_errors = self.get_js_errors
21
+ if not js_errors.nil?
22
+ errors += js_errors
23
+ end
24
24
 
25
- if errors.length > 0 or self.get_http_status.to_i > 299
26
- errors.each do |error|
27
- if error.is_a? Hash
28
- world.log.debug("#{error["message"]} #{error["url"]} #{error["line"]} #{error["column"]}\n#{error["stack"]}")
29
- else
30
- world.log.debug("#{error}")
25
+ if errors.length > 0 or self.get_http_status.to_i > 299
26
+ errors.each do |error|
27
+ if error.is_a? Hash
28
+ world.log.debug("#{error["message"]} #{error["url"]} #{error["line"]} #{error["column"]}\n#{error["stack"]}")
29
+ else
30
+ world.log.debug("#{error}")
31
+ end
31
32
  end
33
+ return true
32
34
  end
33
- return true
35
+ return false
34
36
  end
35
- return false
36
- end
37
37
 
38
38
 
39
- ##
40
- # Retrieve errors from HTML elements, using the error_strings config
41
- # variable
42
- def get_html_errors
43
- result = []
44
- # Need some error strings
45
- if world.has_env_or_config?("error_strings")
46
- begin
47
- # Get the HTML of the page
48
- page_text = @browser.html
49
- # Try to find all errors
50
- world.env_or_config("error_strings").each {|error|
51
- if page_text.include? error
52
- # Add to the result list
53
- result.push error
54
- end
55
- }
56
- rescue RuntimeError => err
57
- # An error?
58
- world.log.debug "Cannot read the html for page #{@browser.url}: #{err}"
39
+ ##
40
+ # Retrieve errors from HTML elements, using the error_strings config
41
+ # variable
42
+ def get_html_errors
43
+ result = []
44
+ # Need some error strings
45
+ if world.has_env_or_config?("error_strings")
46
+ begin
47
+ # Get the HTML of the page
48
+ page_text = @browser.html
49
+ # Try to find all errors
50
+ world.env_or_config("error_strings").each {|error|
51
+ if page_text.include? error
52
+ # Add to the result list
53
+ result.push error
54
+ end
55
+ }
56
+ rescue RuntimeError => err
57
+ # An error?
58
+ world.log.debug "Cannot read the html for page #{@browser.url}: #{err}"
59
+ end
59
60
  end
61
+ # By default we don't have errors
62
+ return result
60
63
  end
61
- # By default we don't have errors
62
- return result
63
- end
64
64
 
65
65
 
66
- ##
67
- # If the proxy is supported, use it to retrieve JS errors.
68
- def get_js_errors
69
- return self.browser.execute_script <<-JS
66
+ ##
67
+ # If the proxy is supported, use it to retrieve JS errors.
68
+ def get_js_errors
69
+ return self.browser.execute_script <<-JS
70
70
  try {
71
71
  return lapis_lazuli.errors;
72
72
  } catch(err){
73
73
  return null;
74
74
  }
75
- JS
76
- end
75
+ JS
76
+ end
77
77
 
78
78
 
79
- ##
80
- # If the proxy is supported, use it get the HTTP status code.
81
- def get_http_status
82
- return self.browser.execute_script <<-JS
83
- try{
84
- return lapis_lazuli.http.statusCode;
85
- } catch(err){
86
- return null;
79
+ ##
80
+ # If the proxy is supported, use it get the HTTP status code.
81
+ def get_http_status
82
+ return self.browser.execute_script('
83
+ function getReq() {
84
+ var req = false;
85
+ if(window.XMLHttpRequest) {
86
+ try {
87
+ req = new XMLHttpRequest();
88
+ } catch(e) {
89
+ req = false;
87
90
  }
88
- JS
89
- end
91
+ } else if(window.ActiveXObject) {
92
+ try {
93
+ req = new ActiveXObject("Microsoft.XMLHTTP");
94
+ } catch(e) {
95
+ req = false;
96
+ }
97
+ }
98
+ if (! req) {
99
+ alert("Your browser does not support XMLHttpRequest.");
100
+ }
101
+ return req;
102
+ }
103
+
104
+ var req = getReq();
105
+
106
+ try {
107
+ req.open("GET", "' + self.browser.url + '", false);
108
+ req.send("");
109
+ } catch (e) {
110
+ success = false;
111
+ error_msg = "Error: " + e;
112
+ }
113
+
114
+ return req.status;
115
+ JS')
116
+ end
90
117
 
91
- end # module Error
92
- end # module BrowserModule
118
+ end # module Error
119
+ end # module BrowserModule
93
120
  end # module LapisLazuli
@@ -4,6 +4,8 @@ Author: "<%= config[:user] %>" <<%= config[:email] %>>
4
4
 
5
5
  # Setup
6
6
 
7
+ See: www.testautomation.info/index.php?title=Installing_ruby_with_cucumber
8
+
7
9
  ## General
8
10
 
9
11
  - Make sure you have ruby 2.0 or later installed.
@@ -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
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'
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