watirmark 5.14.16
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.
- data/app_generators/create_project/create_project_generator.rb +115 -0
- data/app_generators/create_project/templates/features/env.rb.erb +8 -0
- data/app_generators/create_project/templates/features/model_steps.rb.erb +9 -0
- data/app_generators/create_project/templates/features/post_error_steps.rb.erb +15 -0
- data/app_generators/create_project/templates/features/sample.feature.erb +5 -0
- data/app_generators/create_project/templates/features/site_steps.rb.erb +7 -0
- data/app_generators/create_project/templates/generators/controller.rb.erb +9 -0
- data/app_generators/create_project/templates/generators/generate.rb.erb +9 -0
- data/app_generators/create_project/templates/generators/model.rb.erb +7 -0
- data/app_generators/create_project/templates/generators/mvc_generator.rb.erb +100 -0
- data/app_generators/create_project/templates/generators/rbeautify.rb.erb +212 -0
- data/app_generators/create_project/templates/generators/view.rb.erb +16 -0
- data/app_generators/create_project/templates/generators/workflow_loader.rb.erb +1 -0
- data/app_generators/create_project/templates/library/base_controller.rb.erb +9 -0
- data/app_generators/create_project/templates/library/base_view.rb.erb +6 -0
- data/app_generators/create_project/templates/library/configuration.rb.erb +6 -0
- data/app_generators/create_project/templates/library/core_libraries.rb.erb +9 -0
- data/app_generators/create_project/templates/library/loader.rb.erb +23 -0
- data/app_generators/create_project/templates/library/page_load_checker.rb.erb +11 -0
- data/app_generators/create_project/templates/library/post_errors_checker.rb.erb +23 -0
- data/app_generators/create_project/templates/library/project_require_file.rb.erb +8 -0
- data/app_generators/create_project/templates/library/search_controller.rb.erb +12 -0
- data/app_generators/create_project/templates/library/workflows.rb.erb +0 -0
- data/app_generators/create_project/templates/project/config.yml.erb +3 -0
- data/app_generators/create_project/templates/project/gemfile.rb.erb +11 -0
- data/app_generators/create_project/templates/project/rakefile.rb.erb +21 -0
- data/bin/etapestry/Gemfile +11 -0
- data/bin/etapestry/config.yml +3 -0
- data/bin/etapestry/features/etapestry_home.feature +5 -0
- data/bin/etapestry/features/step_definitions/model_steps.rb +9 -0
- data/bin/etapestry/features/step_definitions/post_error_steps.rb +15 -0
- data/bin/etapestry/features/step_definitions/site_steps.rb +7 -0
- data/bin/etapestry/features/support/env.rb +8 -0
- data/bin/etapestry/generators/mvc/mvc_generator.rb +100 -0
- data/bin/etapestry/generators/mvc/rbeautify.rb +212 -0
- data/bin/etapestry/generators/mvc/templates/controller.rb.erb +9 -0
- data/bin/etapestry/generators/mvc/templates/model.rb.erb +7 -0
- data/bin/etapestry/generators/mvc/templates/view.rb.erb +16 -0
- data/bin/etapestry/generators/mvc/templates/workflow_loader.rb.erb +1 -0
- data/bin/etapestry/lib/etapestry.rb +8 -0
- data/bin/etapestry/lib/etapestry/checkers/page_load_checker.rb +11 -0
- data/bin/etapestry/lib/etapestry/checkers/post_errors_checker.rb +23 -0
- data/bin/etapestry/lib/etapestry/configuration.rb +6 -0
- data/bin/etapestry/lib/etapestry/core_libraries.rb +9 -0
- data/bin/etapestry/lib/etapestry/loader.rb +23 -0
- data/bin/etapestry/lib/etapestry/site/base_controller.rb +9 -0
- data/bin/etapestry/lib/etapestry/site/base_view.rb +6 -0
- data/bin/etapestry/lib/etapestry/site/search_controller.rb +12 -0
- data/bin/etapestry/lib/etapestry/workflows.rb +0 -0
- data/bin/etapestry/rakefile.rb +21 -0
- data/bin/etapestry/script/generate.rb +9 -0
- data/bin/twitter/features/hashtag_search.feature +93 -0
- data/bin/twitter/features/step_definitions/hashtag_steps.rb +9 -0
- data/bin/twitter/lib/twitter/workflows/search/result_controller.rb +13 -0
- data/bin/twitter/lib/twitter/workflows/search/result_model.rb +5 -0
- data/bin/twitter/lib/twitter/workflows/search/result_view.rb +19 -0
- data/bin/watirmark +10 -0
- data/lib/watirmark.rb +26 -0
- data/lib/watirmark/at_exit.rb +13 -0
- data/lib/watirmark/configuration.rb +201 -0
- data/lib/watirmark/controller/actions.rb +172 -0
- data/lib/watirmark/controller/assertions.rb +116 -0
- data/lib/watirmark/controller/controller.rb +191 -0
- data/lib/watirmark/controller/dialogs.rb +33 -0
- data/lib/watirmark/controller/matcher.rb +19 -0
- data/lib/watirmark/cucumber/cuke_helper.rb +150 -0
- data/lib/watirmark/cucumber/email_helper.rb +103 -0
- data/lib/watirmark/cucumber/env.rb +9 -0
- data/lib/watirmark/cucumber/hooks.rb +16 -0
- data/lib/watirmark/cucumber/model_helper.rb +34 -0
- data/lib/watirmark/cucumber/transforms.rb +55 -0
- data/lib/watirmark/exceptions.rb +15 -0
- data/lib/watirmark/extensions/ruby_extensions.rb +129 -0
- data/lib/watirmark/extensions/webdriver_extensions.rb +150 -0
- data/lib/watirmark/formatters/snapshot_formatter.rb +23 -0
- data/lib/watirmark/loader.rb +87 -0
- data/lib/watirmark/model.rb +3 -0
- data/lib/watirmark/models/cucumber_helper.rb +49 -0
- data/lib/watirmark/models/debug_methods.rb +21 -0
- data/lib/watirmark/models/default_values.rb +21 -0
- data/lib/watirmark/models/factory.rb +168 -0
- data/lib/watirmark/models/factory_method_generators.rb +84 -0
- data/lib/watirmark/models/factory_methods.rb +72 -0
- data/lib/watirmark/models/trait.rb +35 -0
- data/lib/watirmark/models/upload_csv.rb +24 -0
- data/lib/watirmark/page/keyed_element.rb +63 -0
- data/lib/watirmark/page/page.rb +50 -0
- data/lib/watirmark/page/page_definition.rb +187 -0
- data/lib/watirmark/page/process_page.rb +112 -0
- data/lib/watirmark/page/radio_maps.rb +53 -0
- data/lib/watirmark/profile.rb +22 -0
- data/lib/watirmark/rake/smoketest.rb +17 -0
- data/lib/watirmark/screenshot.rb +127 -0
- data/lib/watirmark/session.rb +115 -0
- data/lib/watirmark/version.rb +5 -0
- data/spec/assertions_spec.rb +95 -0
- data/spec/config_spec.rb +82 -0
- data/spec/controller_actions_spec.rb +91 -0
- data/spec/controller_spec.rb +426 -0
- data/spec/controllers_and_models_spec.rb +52 -0
- data/spec/model_factory_spec.rb +568 -0
- data/spec/model_traits_spec.rb +141 -0
- data/spec/page_spec.rb +127 -0
- data/spec/process_page_spec.rb +163 -0
- data/spec/spec_helper.rb +17 -0
- metadata +238 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Etapestry
|
|
2
|
+
<%= create_modules %>
|
|
3
|
+
class <%= name.camelize %>View < BaseView
|
|
4
|
+
keyword(:keyword_name) { browser.text_field(:id, 'element_id') }
|
|
5
|
+
|
|
6
|
+
def home(model)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def create(model)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def edit(model)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
<%= create_module_end %>
|
|
16
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Etapestry::Loader.load_product '<%= product.downcase %>'
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module Watirmark
|
|
2
|
+
class Session
|
|
3
|
+
|
|
4
|
+
# put in here the appropriate waits
|
|
5
|
+
# to verify that the page has loaded completely, if your app has javascript-loaded content
|
|
6
|
+
def self.page_load
|
|
7
|
+
Watir::Wait.until { Page.browser.url != "about:blank" }
|
|
8
|
+
end
|
|
9
|
+
Watirmark::Session::POST_WAIT_CHECKERS << Proc.new { Watirmark::Session::page_load }
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require 'watirmark/session'
|
|
2
|
+
|
|
3
|
+
module Watirmark
|
|
4
|
+
class Session
|
|
5
|
+
|
|
6
|
+
# Post errors are basically any error messages that
|
|
7
|
+
# appear to the user when a form submission fails. This catches that
|
|
8
|
+
# error and allows the cucumber to catch the error (@@buffer_post_failure)
|
|
9
|
+
# or just throw an exception when an error is seen after a post
|
|
10
|
+
def self.post_errors
|
|
11
|
+
#if Page.browser.table(:class, 'error').present?
|
|
12
|
+
# message = Page.browser.table(:class, 'error').text
|
|
13
|
+
# if @@buffer_post_failure
|
|
14
|
+
# @@post_failure = message.strip
|
|
15
|
+
# else
|
|
16
|
+
# raise Watirmark::PostFailure, message.strip
|
|
17
|
+
# end
|
|
18
|
+
#end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
Watirmark::Session::POST_WAIT_CHECKERS << Proc.new { Watirmark::Session::post_errors }
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require 'watirmark/loader'
|
|
2
|
+
module Etapestry
|
|
3
|
+
class Loader
|
|
4
|
+
class << self
|
|
5
|
+
@@loaded = {}
|
|
6
|
+
|
|
7
|
+
def load_workflow(name)
|
|
8
|
+
load_files name, "*{_view}.rb"
|
|
9
|
+
load_files name, "*{_model}.rb"
|
|
10
|
+
load_files name, "*{_controller}.rb"
|
|
11
|
+
load_files name, "*.rb"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def load_files(name, files)
|
|
15
|
+
Watirmark.loader do
|
|
16
|
+
base_directory File.dirname(__FILE__)
|
|
17
|
+
product 'Etapestry'
|
|
18
|
+
load_files "workflows/#{name}#{files}"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module Etapestry
|
|
2
|
+
class SearchController < BaseController
|
|
3
|
+
|
|
4
|
+
def current_record_visible?
|
|
5
|
+
raise "Method needs to be defined in the subclass and return a true/false value"
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def populate_data
|
|
9
|
+
super unless current_record_visible?
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
File without changes
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
$: << File.expand_path(File.join(File.dirname(__FILE__), 'lib'))
|
|
2
|
+
|
|
3
|
+
# Run a bundle install if running from Jenkins
|
|
4
|
+
begin
|
|
5
|
+
sh "bundle install" if File.dirname(__FILE__) =~ /\/(hudson|mnt)\/workspace\//
|
|
6
|
+
rescue Gem::RemoteFetcher::FetchError
|
|
7
|
+
puts "Unable to connect - retrying #{Time.now}"
|
|
8
|
+
retry
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
require 'bundler/setup'
|
|
12
|
+
require 'cucumber/rake/task'
|
|
13
|
+
|
|
14
|
+
module RakeHelper
|
|
15
|
+
def self.cucumber_task(task_name, files=nil)
|
|
16
|
+
Cucumber::Rake::Task.new(task_name) do |t|
|
|
17
|
+
t.cucumber_opts = "-r features #{FileList[files]} -b --format html -o reports/report.html --format pretty"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
|
3
|
+
|
|
4
|
+
require 'rubigen'
|
|
5
|
+
require 'rubigen/scripts/generate'
|
|
6
|
+
|
|
7
|
+
ARGV.shift if %w(--help -h).include?(ARGV[0])
|
|
8
|
+
RubiGen::Base.use_component_sources! [:rubygems]
|
|
9
|
+
RubiGen::Scripts::Generate.new.run(ARGV)
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
Feature: Searches using the hashtag symbol(#) should return a list of tweets containing that hashtag
|
|
2
|
+
Given I am logged in as a twitter user
|
|
3
|
+
When I enter a search using a hashtag
|
|
4
|
+
Then I expect to see a list of results for that hashtag
|
|
5
|
+
|
|
6
|
+
Background:
|
|
7
|
+
Given I go to the home page
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# This is the test we're going to automate
|
|
12
|
+
|
|
13
|
+
Scenario: Searching for a hashtag should only return results containing that hashtag
|
|
14
|
+
When I search for "#trest"
|
|
15
|
+
Then I should only see tweets containing the term "#blackbaud"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
Scenario: Hashtags in tweets should show as links
|
|
21
|
+
When I create a new tweet "This is a tweet with a #test hashtag"
|
|
22
|
+
Then the tweet should contain "#test"
|
|
23
|
+
|
|
24
|
+
Scenario: Clicking hashtags in tweets should show search results for the hashtag
|
|
25
|
+
When I create a new tweet "This is a tweet to follow with a #test hashtag"
|
|
26
|
+
And I click the hashtag "#test" in the last tweet
|
|
27
|
+
Then I should only see tweets containing the term "#test"
|
|
28
|
+
|
|
29
|
+
Scenario: Multiple hashtags should return results containing *all* hashtags defined (AND search)
|
|
30
|
+
When I search for "#blackbaud #winning"
|
|
31
|
+
Then I should only see tweets containing the terms "#blackbaud" and "#winning"
|
|
32
|
+
|
|
33
|
+
Scenario: Saving a hashtag search should preserve the hashtag in the search
|
|
34
|
+
When I search for "#blackbaud"
|
|
35
|
+
And I save the search
|
|
36
|
+
Then I should see the search in the dropdown saved searches list
|
|
37
|
+
And I should be able to select the search from that list
|
|
38
|
+
And I should only see tweets containing the term "#blackbaud"
|
|
39
|
+
|
|
40
|
+
Scenario: New tweets should periodically show 'N new tweets' at the top of the list
|
|
41
|
+
When I search for "#blackbaud"
|
|
42
|
+
And I create a new tweet "This is a tweet with a #test hashtag using the API" using the API
|
|
43
|
+
Then I should see the new tweets header with "1 new tweet"
|
|
44
|
+
When I click the new tweets header
|
|
45
|
+
Then I should see the tweet "This is a tweet with a #test hashtag using the API"
|
|
46
|
+
|
|
47
|
+
Scenario: Empty search results should display the "No tweet results" message
|
|
48
|
+
When I search for "#this_is_an_empty_search_test"
|
|
49
|
+
Then I should see the search message "No tweet results for #this_is_an_empty_search_test"
|
|
50
|
+
|
|
51
|
+
Scenario: "Top" Tweets should be the default search list
|
|
52
|
+
When I search for "#blackbaud"
|
|
53
|
+
Then the selected search filter should be "Top"
|
|
54
|
+
|
|
55
|
+
Scenario: Clicking "Top" should show the most popular tweets on that hashtag
|
|
56
|
+
When I search for "#blackbaud"
|
|
57
|
+
And I select the search filter "All"
|
|
58
|
+
And I select the search filter "Top"
|
|
59
|
+
Then the selected search filter should be "Top"
|
|
60
|
+
And the tweets should pull from the most popular list for "#blackbaud"
|
|
61
|
+
|
|
62
|
+
Scenario: Clicking "All" should show the most recent tweets on that hashtag
|
|
63
|
+
When I search for "#blackbaud"
|
|
64
|
+
And I select the search filter "All"
|
|
65
|
+
Then the selected search filter should be "All"
|
|
66
|
+
And the tweets should pull from the full list for "#blackbaud"
|
|
67
|
+
|
|
68
|
+
Scenario: Clicking "People you follow" should only show hashtag tweets from your follow list
|
|
69
|
+
When I search for "#blackbaud"
|
|
70
|
+
And I select the search filter "People you follow"
|
|
71
|
+
Then the selected search filter should be "People you follow"
|
|
72
|
+
And the tweets should pull from the people list for "#blackbaud"
|
|
73
|
+
|
|
74
|
+
Scenario: Scrolling to the end of the list should autoload the next 20 matches
|
|
75
|
+
When I search for "#blackbaud"
|
|
76
|
+
And I scroll to the bottom of the page
|
|
77
|
+
Then the next 20 results should load
|
|
78
|
+
And the search should contain more than 20 results
|
|
79
|
+
|
|
80
|
+
Scenario: The max size of the list should be 20 items
|
|
81
|
+
When I search for "#blackbaud"
|
|
82
|
+
Then the search should contain at most 20 results
|
|
83
|
+
|
|
84
|
+
Scenario: Advanced searches should honor a single hashtag
|
|
85
|
+
|
|
86
|
+
Scenario: Advanced searches should honor a multiple hashtags
|
|
87
|
+
|
|
88
|
+
Scenario: Promoted tweets should show regardless of the search terms
|
|
89
|
+
|
|
90
|
+
Scenario: Hitting the enter button should return the same set of results as clicking the looking glass
|
|
91
|
+
|
|
92
|
+
Scenario: Searching for a string (not hashtag) should return results matching the hashtag or the string
|
|
93
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Twitter
|
|
2
|
+
module Search
|
|
3
|
+
class ResultView < BaseView
|
|
4
|
+
private_keyword(:result_container) { browser.div(:id => 'stream-items-id')}
|
|
5
|
+
private_keyword(:results) { result_container.divs(:class, 'content').map(&:text)}
|
|
6
|
+
|
|
7
|
+
class << self
|
|
8
|
+
def home(model)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def create(model)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def edit(model)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
data/bin/watirmark
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
$:<< File.dirname(__FILE__)
|
|
3
|
+
|
|
4
|
+
require 'rubigen'
|
|
5
|
+
require 'rubigen/scripts/generate'
|
|
6
|
+
|
|
7
|
+
source = RubiGen::PathSource.new(:application, File.join(File.dirname(__FILE__), "../app_generators"))
|
|
8
|
+
RubiGen::Base.reset_sources
|
|
9
|
+
RubiGen::Base.append_sources source
|
|
10
|
+
RubiGen::Scripts::Generate.new.run(ARGV, :generator => 'create_project')
|
data/lib/watirmark.rb
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
if RUBY_VERSION != "1.9.3"
|
|
2
|
+
warn "
|
|
3
|
+
************************************************************************
|
|
4
|
+
Using unsupported Ruby version #{RUBY_VERSION}. Please upgrade to 1.9.3
|
|
5
|
+
************************************************************************
|
|
6
|
+
"
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
require 'watirmark/configuration'
|
|
10
|
+
Watirmark::Configuration.instance.reload
|
|
11
|
+
|
|
12
|
+
require 'watirmark/at_exit'
|
|
13
|
+
require 'watir-webdriver'
|
|
14
|
+
require 'watirmark/extensions/webdriver_extensions'
|
|
15
|
+
require 'watirmark/extensions/ruby_extensions'
|
|
16
|
+
require 'watirmark/session'
|
|
17
|
+
require 'watirmark/exceptions'
|
|
18
|
+
require 'watirmark/page/keyed_element'
|
|
19
|
+
require 'watirmark/page/page'
|
|
20
|
+
require 'watirmark/controller/controller'
|
|
21
|
+
require 'american_date'
|
|
22
|
+
require 'uuid'
|
|
23
|
+
require 'watirmark/model'
|
|
24
|
+
require 'watirmark/rake/smoketest'
|
|
25
|
+
require 'active_support/inflector'
|
|
26
|
+
FileUtils.rm_rf('reports/screenshots')
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
require 'singleton'
|
|
2
|
+
require 'logger'
|
|
3
|
+
|
|
4
|
+
module Watirmark
|
|
5
|
+
|
|
6
|
+
class Configuration
|
|
7
|
+
include Singleton
|
|
8
|
+
|
|
9
|
+
def initialize
|
|
10
|
+
@settings = {}
|
|
11
|
+
@runtime_defaults = {}
|
|
12
|
+
reload
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def defaults
|
|
16
|
+
{
|
|
17
|
+
:configfile => nil,
|
|
18
|
+
:hostname => nil,
|
|
19
|
+
:email => 'devnull',
|
|
20
|
+
:closebrowseronexit => false,
|
|
21
|
+
:loglevel => Logger::INFO,
|
|
22
|
+
:uuid => nil,
|
|
23
|
+
:webdriver => :firefox,
|
|
24
|
+
# database
|
|
25
|
+
:dbhostname => nil,
|
|
26
|
+
:dbusername => nil,
|
|
27
|
+
:dbpassword => nil,
|
|
28
|
+
:dbsid => nil,
|
|
29
|
+
:dbport => nil,
|
|
30
|
+
# snapshots
|
|
31
|
+
:snapshotwidth => 1000,
|
|
32
|
+
:snapshotheight => 1000,
|
|
33
|
+
:sandbox => false,
|
|
34
|
+
:projectpath => nil,
|
|
35
|
+
|
|
36
|
+
#to deprecate
|
|
37
|
+
:profile => Hash.new { |h, k| h[k] = Hash.new },
|
|
38
|
+
:profile_name => :undefined,
|
|
39
|
+
|
|
40
|
+
}.merge @runtime_defaults
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def defaults=(x)
|
|
44
|
+
@runtime_defaults.merge! x
|
|
45
|
+
reload
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def update(values)
|
|
49
|
+
values.each_pair { |k, v|
|
|
50
|
+
v = Logger.const_get(v.upcase) if k.to_s == "loglevel" && v.class == String
|
|
51
|
+
self[k] = v
|
|
52
|
+
}
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def inspect
|
|
56
|
+
@settings.inspect
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def reset
|
|
60
|
+
@settings.each_key { |key| @settings.delete key }
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def [](key)
|
|
64
|
+
@settings[key.to_sym]
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def []=(key, value)
|
|
68
|
+
override_method = "#{key}_value".to_sym
|
|
69
|
+
if respond_to? override_method
|
|
70
|
+
@settings[key.to_sym] = self.send override_method, value
|
|
71
|
+
else
|
|
72
|
+
@settings[key.to_sym] = value
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def method_missing(sym, *args)
|
|
77
|
+
if sym.to_s =~ /(.+)=$/
|
|
78
|
+
self[$1] = args.first
|
|
79
|
+
else
|
|
80
|
+
self[sym]
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def db
|
|
85
|
+
@db = nil if (@db && @db.respond_to?(:dbh) && @db.dbh.handle == nil)
|
|
86
|
+
@db ||= WatirmarkDB::DB.new(self.hostname, self.dbhostname, self.dbusername, self.dbpassword, self.dbsid, self.dbport)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
# This will read in ANY variable set in a configuration file
|
|
91
|
+
def read_from_file
|
|
92
|
+
return unless File.exists?(configfile.to_s)
|
|
93
|
+
filename = File.expand_path(configfile)
|
|
94
|
+
case File.extname filename
|
|
95
|
+
when ".txt", ".hudson"
|
|
96
|
+
parse_text_file filename
|
|
97
|
+
when ".yml"
|
|
98
|
+
parse_yaml_file filename
|
|
99
|
+
else
|
|
100
|
+
Watirmark.logger.warn "Unsure how to handle configuration file #{configfile}. Assuming .txt"
|
|
101
|
+
parse_text_file filename
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
alias :read :read_from_file
|
|
106
|
+
|
|
107
|
+
# The variable needs to be set as a default here or in the
|
|
108
|
+
# library to be read from the environment
|
|
109
|
+
def read_from_environment
|
|
110
|
+
@settings.each_key do |var|
|
|
111
|
+
next if var.to_s.upcase == "USERNAME"
|
|
112
|
+
env = ENV[var.to_s.upcase]
|
|
113
|
+
if var == :webdriver
|
|
114
|
+
ENV['JOB_NAME']=~ /WEBDRIVER=(\w+)/
|
|
115
|
+
env ||= $1
|
|
116
|
+
end
|
|
117
|
+
update var.to_sym => env if env
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def reload
|
|
122
|
+
update(defaults)
|
|
123
|
+
read_from_file
|
|
124
|
+
read_from_environment
|
|
125
|
+
initialize_logger
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def logger
|
|
129
|
+
@logger ||= begin
|
|
130
|
+
log = Logger.new STDOUT
|
|
131
|
+
log.formatter = proc {|severity, datetime, progname, msg| "[#{datetime}] #{msg}\n"}
|
|
132
|
+
log
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def loglevel=(x)
|
|
137
|
+
logger.level = x
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
private
|
|
141
|
+
|
|
142
|
+
def update_key key, value
|
|
143
|
+
case value
|
|
144
|
+
when 'true'
|
|
145
|
+
update key.to_sym => true
|
|
146
|
+
when 'false'
|
|
147
|
+
update key.to_sym => false
|
|
148
|
+
when /^:(.+)/
|
|
149
|
+
update key.to_sym => $1.to_sym
|
|
150
|
+
when /^\d+\s*$/
|
|
151
|
+
update key.to_sym => value.to_i
|
|
152
|
+
when /^(\d*\.\d+)\s*$/
|
|
153
|
+
update key.to_sym => value.to_f
|
|
154
|
+
else
|
|
155
|
+
update key.to_sym => value
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def update_profile key
|
|
160
|
+
return unless key =~ /^profile\[:(.+)\]\[:(.+)\]/
|
|
161
|
+
logger.warn "profiles are going to be deprecated. Please use YAML and salesforce_sites"
|
|
162
|
+
if self[:profile][$1.to_sym] == nil
|
|
163
|
+
self[:profile] = ({$1.to_sym => {$2.to_sym => value.to_s}})
|
|
164
|
+
else
|
|
165
|
+
self[:profile][$1.to_sym].merge!({$2.to_sym => value.to_s})
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def update_profile_yaml
|
|
170
|
+
if self[:salesforce_sites] && self[:salesforce_sites]["active"]
|
|
171
|
+
site = self[:salesforce_sites]["active"]
|
|
172
|
+
self[:salesforce_sites][site].each do |key, value|
|
|
173
|
+
self[key.to_sym] = value
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def parse_yaml_file filename
|
|
179
|
+
YAML.load_file(filename).each_pair { |key, value| update_key key, value }
|
|
180
|
+
update_profile_yaml
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# This is the old-style method of using a config.txt
|
|
184
|
+
def parse_text_file filename
|
|
185
|
+
Watirmark.logger.warn "Warning: Deprecated use of config.txt. Please use config.yml instead"
|
|
186
|
+
IO.readlines(filename).each do |line|
|
|
187
|
+
line.strip! # Remove all extraneous whitespace
|
|
188
|
+
line.sub!(/#.*$/, "") # Remove comments
|
|
189
|
+
next unless line.length > 0 # Anything left?
|
|
190
|
+
(key, value) = line.split(/\s*=\s*/, 2)
|
|
191
|
+
update_profile key
|
|
192
|
+
update_key key, value
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def self.logger
|
|
198
|
+
Configuration.instance.logger ||= Logger.new(STDOUT)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
end
|