taza 0.5.0 → 0.8.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 (55) hide show
  1. data/History.txt +33 -0
  2. data/Manifest.txt +39 -9
  3. data/README.txt +29 -7
  4. data/Rakefile +72 -13
  5. data/bin/taza +16 -3
  6. data/generators/flow/flow_generator.rb +57 -0
  7. data/generators/flow/templates/flow.rb.erb +12 -0
  8. data/generators/page/page_generator.rb +58 -0
  9. data/generators/page/templates/functional_page_spec.rb.erb +8 -0
  10. data/generators/page/templates/page.rb.erb +8 -0
  11. data/generators/site/site_generator.rb +55 -0
  12. data/generators/site/templates/site.rb.erb +10 -0
  13. data/generators/site/templates/site.yml.erb +3 -0
  14. data/lib/app_generators/taza/taza_generator.rb +76 -0
  15. data/lib/app_generators/taza/templates/config.yml.erb +3 -0
  16. data/lib/{taza/generators → app_generators/taza}/templates/rakefile.rb.erb +0 -0
  17. data/lib/app_generators/taza/templates/spec_helper.rb.erb +11 -0
  18. data/lib/taza.rb +44 -5
  19. data/lib/taza/browser.rb +40 -0
  20. data/lib/taza/browsers/ie_watir.rb +8 -0
  21. data/lib/taza/browsers/safari_watir.rb +8 -0
  22. data/lib/taza/flow.rb +45 -0
  23. data/lib/taza/page.rb +66 -19
  24. data/lib/taza/settings.rb +36 -0
  25. data/lib/taza/site.rb +122 -11
  26. data/lib/taza/tasks.rb +26 -34
  27. data/spec/browser_spec.rb +72 -0
  28. data/spec/flow_generator_spec.rb +70 -0
  29. data/spec/page_generator_spec.rb +57 -0
  30. data/spec/page_spec.rb +82 -0
  31. data/spec/platform/osx/browser_spec.rb +14 -0
  32. data/spec/platform/windows/browser_spec.rb +14 -0
  33. data/spec/project_generator_spec.rb +42 -0
  34. data/spec/sandbox/config.yml +3 -0
  35. data/spec/sandbox/config/config.yml +1 -0
  36. data/spec/sandbox/config/site_name.yml +5 -0
  37. data/spec/sandbox/flows/batman.rb +2 -0
  38. data/spec/sandbox/flows/robin.rb +4 -0
  39. data/spec/sandbox/pages/foo/bar.rb +9 -0
  40. data/spec/settings_spec.rb +88 -0
  41. data/spec/site_generator_spec.rb +53 -0
  42. data/spec/site_spec.rb +239 -0
  43. data/spec/spec_helper.rb +49 -0
  44. data/spec/taza_bin_spec.rb +14 -0
  45. data/spec/taza_spec.rb +12 -0
  46. data/spec/taza_tasks_spec.rb +27 -0
  47. data/spec/unit_helper_spec.rb +14 -0
  48. metadata +103 -13
  49. data/lib/taza/generators.rb +0 -4
  50. data/lib/taza/generators/base.rb +0 -33
  51. data/lib/taza/generators/page.rb +0 -22
  52. data/lib/taza/generators/project.rb +0 -18
  53. data/lib/taza/generators/site.rb +0 -24
  54. data/lib/taza/generators/templates/page.rb.erb +0 -6
  55. data/lib/taza/generators/templates/site.rb.erb +0 -6
@@ -0,0 +1,36 @@
1
+ require 'activesupport'
2
+
3
+ module Taza
4
+ class Settings
5
+ def self.config(site_name)
6
+ env_settings = {}
7
+ env_settings[:browser] = ENV['browser'].to_sym if ENV['browser']
8
+ env_settings[:driver] = ENV['driver'].to_sym if ENV['driver']
9
+ env_settings[:timeout] = ENV['timeout'] if ENV['timeout']
10
+ env_settings[:server_ip] = ENV['server_ip'] if ENV['server_ip']
11
+ env_settings[:server_port] = ENV['server_port'] if ENV['server_port']
12
+ env_settings = {:browser=>:firefox,:driver=>:selenium}.merge(config_file.merge(env_settings))
13
+ site_file(site_name).merge(env_settings)
14
+ end
15
+
16
+ def self.config_file # :nodoc:
17
+ YAML.load_file(config_file_path)
18
+ end
19
+
20
+ def self.config_file_path # :nodoc:
21
+ File.join(config_folder,'config.yml')
22
+ end
23
+
24
+ def self.config_folder # :nodoc:
25
+ File.join(path,'config')
26
+ end
27
+
28
+ def self.site_file(site_name) # :nodoc:
29
+ YAML.load_file(File.join(config_folder,"#{site_name.underscore}.yml"))[ENV['TAZA_ENV']]
30
+ end
31
+
32
+ def self.path # :nodoc:
33
+ '.'
34
+ end
35
+ end
36
+ end
data/lib/taza/site.rb CHANGED
@@ -2,27 +2,138 @@ require 'rubygems'
2
2
  require 'activesupport'
3
3
 
4
4
  module Taza
5
+ # An abstraction of a website, but more really a container for a sites pages.
6
+ #
7
+ # You can generate a site by performing the following command:
8
+ # $ ./script/generate site google
9
+ #
10
+ # This will generate a site file for google, a flows folder, and a pages folder in lib
11
+ #
12
+ # Example:
13
+ #
14
+ # require 'taza'
15
+ #
16
+ # class Google < Taza::Site
17
+ #
18
+ # end
5
19
  class Site
6
- def initialize
20
+ @@before_browser_closes = Proc.new() {}
21
+ # Use this to do something with the browser before it closes, but note that it is a class method which
22
+ # means that this will get called for any instance of a site.
23
+ #
24
+ # Here's an example of how you might use it to print the DOM output of a browser before it closes:
25
+ #
26
+ # Taza::Site.before_browser_closes do |browser|
27
+ # puts browser.html
28
+ # end
29
+ def self.before_browser_closes(&block)
30
+ @@before_browser_closes = block
31
+ end
32
+ attr_accessor :browser
33
+
34
+ # A site can be called a few different ways
35
+ #
36
+ # The following example creates a new browser object and closes it:
37
+ # Google.new do
38
+ # google.search.set "taza"
39
+ # google.submit.click
40
+ # end
41
+ #
42
+ # This example will create a browser object but not close it:
43
+ # Google.new.search.set "taza"
44
+ #
45
+ # Sites can take a couple of parameters in the constructor:
46
+ # :browser => a browser object to act on instead of creating one automatically
47
+ # :url => the url of where to start the site
48
+ def initialize(params={})
49
+ @module_name = self.class.parent.to_s
50
+ @class_name = self.class.to_s.split("::").last
7
51
  define_site_pages
52
+ config = Settings.config(@class_name)
53
+ if params[:browser]
54
+ @browser = params[:browser]
55
+ else
56
+ @browser = Browser.create(config)
57
+ @i_created_browser = true
58
+ end
59
+ @browser.goto(params[:url] || config[:url])
60
+
61
+ if block_given?
62
+ begin
63
+ yield self
64
+ rescue => site_block_exception
65
+ ensure
66
+ begin
67
+ @@before_browser_closes.call(browser)
68
+ rescue => before_browser_closes_block_exception
69
+ end
70
+ close_browser_and_raise_if site_block_exception || before_browser_closes_block_exception
71
+ end
72
+ end
8
73
  end
9
74
 
10
- def define_site_pages
11
- Dir.glob(path) do |file|
12
- require file
75
+ def self.settings # :nodoc:
76
+ Taza::Settings.site_file(self.name.to_s.split("::").last)
77
+ end
78
+
79
+ def close_browser_and_raise_if original_error # :nodoc:
80
+ begin
81
+ if @i_created_browser
82
+ @browser.close
83
+ end
84
+ ensure
85
+ raise original_error if original_error
86
+ end
87
+ end
13
88
 
89
+ def define_site_pages # :nodoc:
90
+ Dir.glob(pages_path) do |file|
91
+ require file
14
92
  page_name = File.basename(file,'.rb')
93
+ page_class = "#{@module_name}::#{page_name.camelize}"
15
94
  self.class.class_eval <<-EOS
16
- def #{page_name}
17
- yield '#{page_name}'.camelcase.constantize.new
18
- end
95
+ def #{page_name}
96
+ page = '#{page_class}'.constantize.new
97
+ page.browser = @browser
98
+ yield page if block_given?
99
+ page
100
+ end
19
101
  EOS
20
102
  end
21
103
  end
22
104
 
23
- def path
24
- File.join('pages',self.class.to_s.underscore,'*.rb')
105
+ # This is used to call a flow belonging to the site
106
+ #
107
+ # Example:
108
+ # Google.new do |google|
109
+ # google.flow(:perform_search, :query => "taza")
110
+ # end
111
+ #
112
+ # Where the flow would be defined under lib/sites/google/flows/perform_search.rb and look like:
113
+ # class PerformSearch < Taza::Flow
114
+ # alias :google :site
115
+ #
116
+ # def run(params={})
117
+ # google.search.set params[:query]
118
+ # google.submit.click
119
+ # end
120
+ # end
121
+ def flow(name,params={})
122
+ require File.join(path,'flows',name.to_s.underscore)
123
+ flow_class = "#{@module_name}::#{name.to_s.camelize}".constantize
124
+ flow_class.new(self).run(params)
125
+ end
126
+
127
+ def pages_path # :nodoc:
128
+ File.join(path,'pages','*.rb')
129
+ end
130
+
131
+ def path # :nodoc:
132
+ File.join(base_path,'lib','sites',@class_name.underscore)
25
133
  end
26
- end
27
- end
28
134
 
135
+ def base_path # :nodoc:
136
+ '.'
137
+ end
138
+ end
139
+ end
data/lib/taza/tasks.rb CHANGED
@@ -1,46 +1,38 @@
1
1
  require 'rake'
2
2
  require 'rake/testtask'
3
3
  require 'rubygems'
4
- require 'taglob'
4
+ require 'taglob/rake/tasks'
5
5
  require 'spec/rake/spectask'
6
- require 'taza/generators'
7
6
 
8
- private
9
- def get_tagged_files(test_file_pattern)
10
- Dir.taglob(test_file_pattern,ENV['tags'])
11
- end
12
-
13
- def validate_required_environment_input_present(error_message, *environment_variable_keys)
14
- environment_variable_keys.each do |environment_variable_key|
15
- if ENV[environment_variable_key].nil?
16
- STDERR.puts error_message
17
- exit 1
18
- end
7
+ namespace :spec do
8
+ def format_options(file_name)
9
+ file_name = "artifacts/#{file_name}/index.html"
10
+ dir_name = File.dirname(file_name)
11
+ FileUtils.mkdir_p(dir_name) unless File.directory?(dir_name)
12
+ ["--format","html:#{file_name}","--format","p"]
19
13
  end
20
- end
21
-
22
- public
23
14
 
24
- desc "invoke tests by tag"
25
- Rake::TestTask.new :test_tag do |t|
26
- t.test_files = get_tagged_files('test/**/test_*.rb')
27
- end
15
+ desc "Run all functional specs"
16
+ Spec::Rake::SpecTask.new :functional do |t|
17
+ t.spec_files = 'spec/functional/**/*_spec.rb'
18
+ t.spec_opts << format_options("functional/all")
19
+ end
20
+ desc "Run all integration specs"
21
+ Spec::Rake::SpecTask.new :integration do |t|
22
+ t.spec_files = 'spec/integration/**/*_spec.rb'
23
+ t.spec_opts << format_options("integration/all")
24
+ end
28
25
 
29
- desc "invoke specs by tag"
30
- Spec::Rake::SpecTask.new :spec_tag do |t|
31
- t.spec_files = get_tagged_files('spec/**/*_spec.rb')
32
- end
26
+ namespace :functional do
27
+ Dir.glob('./spec/functional/*/').each do |dir|
28
+ site_name = File.basename(dir)
33
29
 
34
- namespace :generate do
35
- desc "generate a site(rake generate:site name=foo)"
36
- task :site do
37
- validate_required_environment_input_present("Usage: rake generate:site name=the_site_name",'name')
38
- Taza::Generators::Site.new(ENV['name']).generate
39
- end
30
+ desc "Run all functional specs for #{site_name}"
31
+ Spec::Rake::SpecTask.new site_name.to_sym do |t|
32
+ t.spec_files = "#{dir}**/*_spec.rb"
33
+ t.spec_opts << format_options("functional/#{site_name}/all")
34
+ end
40
35
 
41
- desc "generate a page(rake generate:page site=foo page=bar)"
42
- task :page do
43
- validate_required_environment_input_present("Usage: rake generate:page name=the_page_name site=the_site_name",'name','site')
44
- Taza::Generators::Page.new(ENV['name'],ENV['site']).generate
36
+ end
45
37
  end
46
38
  end
@@ -0,0 +1,72 @@
1
+ require 'spec/spec_helper'
2
+ require 'taza/browser'
3
+ require 'taza/settings'
4
+ require 'selenium'
5
+ require 'firewatir'
6
+
7
+ describe Taza::Browser do
8
+
9
+ before :each do
10
+ Taza::Settings.stubs(:config_file).returns({})
11
+ ENV['TAZA_ENV'] = 'isolation'
12
+ ENV['server_port'] = nil
13
+ ENV['server_ip'] = nil
14
+ ENV['browser'] = nil
15
+ ENV['driver'] = nil
16
+ ENV['timeout'] = nil
17
+ end
18
+
19
+ it "should be able to create a watir driver" do
20
+ Taza::Browser.expects(:create_watir_ie)
21
+ Taza::Browser.create(:browser => :ie, :driver => :watir)
22
+ end
23
+
24
+ it "should be able to create a firewatir driver" do
25
+ Taza::Browser.expects(:create_watir_firefox)
26
+ Taza::Browser.create(:browser => :firefox,:driver => :watir)
27
+ end
28
+
29
+ it "should be able to create a safariwatir driver" do
30
+ Taza::Browser.expects(:create_watir_safari)
31
+ Taza::Browser.create(:browser => :safari,:driver => :watir)
32
+ end
33
+
34
+ it "should raise unknown browser error for unsupported watir browsers" do
35
+ lambda { Taza::Browser.create(:browser => :foo_browser_9000,:driver => :watir) }.should raise_error(BrowserUnsupportedError)
36
+ end
37
+
38
+ it "should use params browser type when creating selenium" do
39
+ browser_type = :opera
40
+ Selenium::SeleniumDriver.expects(:new).with(anything,anything,'*opera',anything)
41
+ Taza::Browser.create(:browser => browser_type, :driver => :selenium)
42
+ end
43
+
44
+ it "should raise selenium unsupported browser error" do
45
+ Taza::Browser.create(:browser => :foo, :driver => :selenium)
46
+ end
47
+
48
+ it "should be able to create a selenium instance" do
49
+ browser = Taza::Browser.create(:browser => :firefox, :driver => :selenium)
50
+ browser.should be_a_kind_of(Selenium::SeleniumDriver)
51
+ end
52
+
53
+ it "should use environment settings for server port and ip" do
54
+ Taza::Settings.stubs(:path).returns(File.join('spec','sandbox'))
55
+ ENV['server_port'] = 'server_port'
56
+ ENV['server_ip'] = 'server_ip'
57
+ Selenium::SeleniumDriver.expects(:new).with('server_ip','server_port',anything,anything)
58
+ Taza::Browser.create(Taza::Settings.config("SiteName"))
59
+ end
60
+
61
+ it "should use environment settings for timeout" do
62
+ Taza::Settings.stubs(:path).returns(File.join('spec','sandbox'))
63
+ ENV['timeout'] = 'timeout'
64
+ Selenium::SeleniumDriver.expects(:new).with(anything,anything,anything,'timeout')
65
+ Taza::Browser.create(Taza::Settings.config("SiteName"))
66
+ end
67
+
68
+ it "should create firewatir instance" do
69
+ FireWatir::Firefox.expects(:new)
70
+ Taza::Browser.create(:browser => :firefox, :driver => :watir)
71
+ end
72
+ end
@@ -0,0 +1,70 @@
1
+ require 'spec/spec_helper'
2
+ require 'rubygems'
3
+ require 'fileutils'
4
+ require 'taza'
5
+ require 'vendor/gems/gems/rubigen-1.3.2/test/test_generator_helper'
6
+
7
+ class Taza::Site
8
+ def flows
9
+ flows = []
10
+ Dir.glob(File.join(path,'flows','*.rb')).each do |file|
11
+ require file
12
+
13
+ flows << "#{self.class.parent.to_s}::#{File.basename(file,'.rb').camelize}".constantize
14
+ end
15
+ flows
16
+ end
17
+ end
18
+
19
+ describe "Flow Generation" do
20
+ include RubiGen::GeneratorTestHelper
21
+ include Helpers::Generator
22
+ include Helpers::Taza
23
+
24
+ before :all do
25
+ @site_name = "Foo"
26
+ @site_folder = File.join(PROJECT_FOLDER,'lib','sites',"gap")
27
+ @site_file = File.join(PROJECT_FOLDER,'lib','sites',"gap.rb")
28
+ @flow_name = "CheckOut"
29
+ end
30
+
31
+ before :each do
32
+ run_generator('taza', [APP_ROOT], generator_sources)
33
+ @site_class = generate_site(@site_name)
34
+ end
35
+
36
+ after :each do
37
+ bare_teardown
38
+ end
39
+
40
+ it "should give you usage if you do not give two arguments" do
41
+ FlowGenerator.any_instance.expects(:usage)
42
+ lambda { run_generator('flow', [@flow_name], generator_sources) }.should raise_error
43
+ end
44
+
45
+ it "should give you usage if you give a site that does not exist" do
46
+ FlowGenerator.any_instance.expects(:usage)
47
+ $stderr.expects(:puts).with(regexp_matches(/NoSuchSite/))
48
+ lambda { run_generator('flow', [@flow_name,"NoSuchSite"], generator_sources) }.should raise_error
49
+ end
50
+
51
+ it "should generate flows that will not have namespace collisions with pages" do
52
+ flow_name = "SignIn"
53
+ run_generator('flow', [flow_name,@site_class.to_s], generator_sources)
54
+ run_generator('page', [flow_name,@site_class.to_s], generator_sources)
55
+ stub_settings
56
+ stub_browser
57
+ site = @site_class.new
58
+ site.flow(:sign_in)
59
+ site.sign_in_page
60
+ end
61
+
62
+ it "should generate flows that will not have namespace collisions with other sites' flows" do
63
+ new_site_class = generate_site('Pag')
64
+ run_generator('flow', [@flow_name,@site_class.to_s], generator_sources)
65
+ run_generator('flow', [@flow_name,new_site_class.to_s], generator_sources)
66
+ stub_settings
67
+ stub_browser
68
+ (@site_class.new.flows & new_site_class.new.flows).should be_empty
69
+ end
70
+ end
@@ -0,0 +1,57 @@
1
+ require 'spec/spec_helper'
2
+ require 'rubygems'
3
+ require 'fileutils'
4
+ require 'taza'
5
+ require 'vendor/gems/gems/rubigen-1.3.2/test/test_generator_helper'
6
+
7
+ describe "Page Generation" do
8
+ include RubiGen::GeneratorTestHelper
9
+ include Helpers::Generator
10
+ include Helpers::Taza
11
+
12
+ before :all do
13
+ @page_name = "CheckOut"
14
+ end
15
+
16
+ before :each do
17
+ run_generator('taza', [APP_ROOT], generator_sources)
18
+ @site_class = generate_site('Gap')
19
+ end
20
+
21
+ after :each do
22
+ bare_teardown
23
+ end
24
+
25
+ it "should give you usage if you do not give two arguments" do
26
+ PageGenerator.any_instance.expects(:usage)
27
+ lambda { run_generator('page', [@page_name], generator_sources) }.should raise_error
28
+ end
29
+
30
+ it "should give you usage if you give a site that does not exist" do
31
+ PageGenerator.any_instance.expects(:usage)
32
+ $stderr.expects(:puts).with(regexp_matches(/NoSuchSite/))
33
+ lambda { run_generator('page', [@page_name,"NoSuchSite"], generator_sources) }.should raise_error
34
+ end
35
+
36
+ it "should generate a page spec that can be required" do
37
+ run_generator('page', [@page_name,@site_class.to_s], generator_sources)
38
+ page_functional_spec = File.join(PROJECT_FOLDER,'spec','functional',@site_class.to_s.underscore,'check_out_page_spec.rb')
39
+ system("ruby -c #{page_functional_spec} > #{null_device}").should be_true
40
+ end
41
+
42
+ it "should be able to access the generated page from the site" do
43
+ run_generator('page', [@page_name,@site_class.to_s], generator_sources)
44
+ stub_settings
45
+ stub_browser
46
+ @site_class.new.check_out_page
47
+ end
48
+
49
+ it "should be able to access the generated page for its site" do
50
+ stub_browser
51
+ stub_settings
52
+ new_site_class = generate_site('Pag')
53
+ run_generator('page', [@page_name,@site_class.to_s], generator_sources)
54
+ run_generator('page', [@page_name,new_site_class.to_s], generator_sources)
55
+ new_site_class.new.check_out_page.class.should_not eql(@site_class.new.check_out_page.class)
56
+ end
57
+ end