selenium-webdriver-viewers 0.0.1

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/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Michael Collas
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,17 @@
1
+ = selenium-webdriver-viewers
2
+
3
+ Description goes here.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
13
+ * Send me a pull request. Bonus points for topic branches.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2010 Michael Collas. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,67 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "selenium-webdriver-viewers"
8
+ gem.summary = 'Makes page objects and views for tests using selenium-webdriver.'
9
+ gem.description = <<-END_DESCRIPTION
10
+ This gem makes it easy to create page and web viewer objects for use by tests that use selenium-webdriver. By
11
+ using page and viewer objects, you can decouple your tests from the html details so that they can focus
12
+ instead on describing the behaviour of your application.
13
+ END_DESCRIPTION
14
+ gem.email = "mcollas@yahoo.com"
15
+ gem.homepage = "http://github.com/michaelcollas/selenium-webdriver-viewers"
16
+ gem.authors = ["Michael Collas"]
17
+ gem.add_development_dependency "rspec", ">= 1.2.9"
18
+ gem.add_development_dependency "reek", ">= 1.2.8"
19
+ gem.add_development_dependency "sexp_processor", ">= 3.0.4"
20
+ gem.files.exclude('.gitignore')
21
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
22
+ end
23
+ Jeweler::GemcutterTasks.new
24
+ rescue LoadError
25
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
26
+ end
27
+
28
+ require 'spec/rake/spectask'
29
+ Spec::Rake::SpecTask.new(:spec) do |spec|
30
+ spec.libs << 'lib' << 'spec'
31
+ spec.spec_files = FileList['spec/**/*_spec.rb']
32
+ end
33
+
34
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
35
+ spec.libs << 'lib' << 'spec'
36
+ spec.pattern = 'spec/**/*_spec.rb'
37
+ spec.rcov = true
38
+ end
39
+
40
+ task :spec => :check_dependencies
41
+
42
+ begin
43
+ require 'reek/rake/task'
44
+ Reek::Rake::Task.new do |t|
45
+ t.fail_on_error = true
46
+ t.verbose = false
47
+ t.source_files = 'lib/**/*.rb'
48
+ t.reek_opts << ' --quiet'
49
+ t.ruby_opts << '-r' << 'rubygems'
50
+ end
51
+ rescue LoadError
52
+ task :reek do
53
+ abort "Reek is not available. In order to run reek, you must: sudo gem install reek"
54
+ end
55
+ end
56
+
57
+ task :default => :spec
58
+
59
+ require 'rake/rdoctask'
60
+ Rake::RDocTask.new do |rdoc|
61
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
62
+
63
+ rdoc.rdoc_dir = 'rdoc'
64
+ rdoc.title = "selenium-webdriver-viewers #{version}"
65
+ rdoc.rdoc_files.include('README*')
66
+ rdoc.rdoc_files.include('lib/**/*.rb')
67
+ end
data/TODO ADDED
@@ -0,0 +1,14 @@
1
+ This project
2
+ ============
3
+ licence
4
+ attributes with different read/write types
5
+ samples
6
+ documentation
7
+
8
+ Related projects
9
+ ================
10
+ rspec-rails integration
11
+ cucumber integration
12
+ interaction objects
13
+ state objects
14
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,61 @@
1
+ require 'selenium-webdriver'
2
+ require 'selenium/webdriver/navigation'
3
+
4
+ module BrowserInstance
5
+
6
+ class << self
7
+
8
+ def base_url=(new_value)
9
+ @base_url = new_value
10
+ @browser.navigate.base_url = @base_url if @browser
11
+ end
12
+
13
+ def base_url
14
+ @base_url || ENV['BASE_URL'] || ''
15
+ end
16
+
17
+ def browser_instance
18
+ @browser ||= create_browser
19
+ end
20
+
21
+ def create_browser
22
+ browser = Selenium::WebDriver.for :firefox
23
+ browser.navigate.extend(BaseUrl).base_url = base_url
24
+ browser
25
+ end
26
+
27
+ def quit
28
+ return unless @browser
29
+ @browser.quit
30
+ @browser = nil
31
+ end
32
+
33
+ end
34
+
35
+ def browser
36
+ BrowserInstance.browser_instance
37
+ end
38
+
39
+ end
40
+
41
+ module BaseUrl
42
+
43
+ def self.extended(target)
44
+ super
45
+ class << target
46
+ alias_method :to_absolute, :to
47
+ alias_method :to, :to_relative
48
+ end
49
+ end
50
+
51
+ def to_relative(new_location)
52
+ to_absolute(@base_url + new_location)
53
+ end
54
+
55
+ def base_url=(base)
56
+ @base_url = base
57
+ end
58
+
59
+ end
60
+
61
+
@@ -0,0 +1,43 @@
1
+ module WebViewer
2
+
3
+ # ElementReader fetches a Selenium::WebDriver::Element for a particular selector. If the selector
4
+ # requires parameters, ElementReader defers reading from WebDriver until the parameters are
5
+ # provided using the [] method.
6
+ class ElementReader
7
+
8
+ def initialize(viewer, selector, selector_type)
9
+ @viewer = viewer
10
+ @selector = selector
11
+ @selector_type = selector_type
12
+ end
13
+
14
+ def requires_parameters?
15
+ @selector.respond_to?(:call) && @selector.respond_to?(:arity) && @selector.arity > 0
16
+ end
17
+
18
+ def callable_selector?
19
+ @selector.respond_to?(:call)
20
+ end
21
+
22
+ # return either self or element depending on whether selector needs parameters
23
+ def get(*arguments)
24
+ return element unless callable_selector?
25
+ if (arguments.length > 0) || !requires_parameters?
26
+ element(@selector.call(*arguments))
27
+ else
28
+ self
29
+ end
30
+ end
31
+
32
+ def [](*arguments)
33
+ selector_text = @selector.call(*arguments)
34
+ self.element(selector_text)
35
+ end
36
+
37
+ def element(selector_text = @selector)
38
+ @viewer.find_element(@selector_type, selector_text)
39
+ end
40
+
41
+ end
42
+
43
+ end
@@ -0,0 +1,50 @@
1
+ module WebViewer
2
+
3
+ # ElementValueReader acts on a Selenium::WebDriver::Element by fetching its value, clicking on it,
4
+ # reading its text, etc.
5
+ class ElementValueReader
6
+
7
+ def initialize(element_reader, output_type)
8
+ @element_reader = element_reader
9
+ @output_type = output_type
10
+ end
11
+
12
+ # return either self or element_value depending on whether selector needs parameters
13
+ def get
14
+ if @element_reader.requires_parameters?
15
+ self
16
+ else
17
+ element_value
18
+ end
19
+ end
20
+
21
+ def [](*args)
22
+ element_value(*args)
23
+ end
24
+
25
+ def []=(*arguments)
26
+ value_to_assign = arguments.pop
27
+ element = @element_reader.get(*arguments)
28
+ ElementValueWriter.new(element, @output_type).value = value_to_assign
29
+ end
30
+
31
+ def element_value(*arguments)
32
+ if (Class === @output_type)
33
+ element_as_viewer(*arguments)
34
+ elsif [:auto, :link, :select_by_text, :select_by_value].include? @output_type
35
+ raise "not yet implemented"
36
+ else
37
+ @element_reader.get(*arguments).send(@output_type)
38
+ end
39
+ end
40
+
41
+ def element_as_viewer(*arguments)
42
+ viewer = @output_type.new
43
+ base_element_proc = lambda { @element_reader.get(*arguments) }
44
+ viewer.instance_variable_set(:@base_element_proc, base_element_proc)
45
+ viewer
46
+ end
47
+
48
+ end
49
+
50
+ end
@@ -0,0 +1,19 @@
1
+ module WebViewer
2
+
3
+ # ElementValueWriter assigns a value to a Selenium::WebDriver::Element. It uses the element_type
4
+ # parameter passed in the constructor to determine how to write to the element.
5
+ class ElementValueWriter
6
+
7
+ def initialize(web_element, element_type)
8
+ @web_element = web_element
9
+ @element_type = element_type
10
+ end
11
+
12
+ def value=(new_value)
13
+ # do smart things with element_type in here
14
+ @web_element.value = new_value
15
+ end
16
+
17
+ end
18
+
19
+ end
data/lib/page.rb ADDED
@@ -0,0 +1,45 @@
1
+ require 'browser-instance'
2
+ require 'viewer'
3
+
4
+ module WebPage
5
+
6
+ def self.included(target)
7
+ super
8
+ target.extend ClassMethods
9
+ end
10
+
11
+ def load
12
+ if respond_to?(:url)
13
+ navigate.to_absolute(url)
14
+ elsif respond_to?(:path)
15
+ navigate.to_relative(path)
16
+ end
17
+ self
18
+ end
19
+
20
+ module ClassMethods
21
+
22
+ def url(url_value)
23
+ define_method(:url) { url_value }
24
+ end
25
+
26
+ def path(path_value)
27
+ define_method(:path) { path_value }
28
+ end
29
+
30
+ def load
31
+ new.load
32
+ end
33
+
34
+ end
35
+
36
+ end
37
+
38
+ # WebPageObject is a base class for web viewers that represent a whole page. In addition to
39
+ # all the normal features of a web viewer, a web page object has url or path, and can
40
+ # navigate to the url or path using the load method.
41
+ class WebPageObject
42
+ include BrowserInstance
43
+ include WebViewer
44
+ include WebPage
45
+ end
@@ -0,0 +1,2 @@
1
+ require 'viewer'
2
+ require 'page'
data/lib/viewer.rb ADDED
@@ -0,0 +1,96 @@
1
+ require 'forwardable'
2
+ require 'browser-instance'
3
+ require 'webdriver-extensions'
4
+ require 'element_reader'
5
+ require 'element_value_reader'
6
+ require 'element_value_writer'
7
+
8
+ module WebViewer
9
+
10
+ extend Forwardable
11
+ def_delegators :browser, :close, :current_url, :execute_script, :get, :manage, :navigate, :page_source,
12
+ :save_screenshot, :screenshot_as, :script, :switch_to, :title, :visible=, :visible?,
13
+ :window_handle, :window_handles
14
+ def_delegators :base_element, :[], :all, :attribute, :clear, :click, :displayed?, :drag_and_drop_by, :drag_and_drop_on,
15
+ :enabled?, :find_element, :find_elements, :first, :hover, :location, :ref, :select, :selected?,
16
+ :send_key, :send_keys, :size, :style, :submit, :tag_name, :text, :toggle, :value,
17
+ :element_present?, :wait_for_element_present
18
+
19
+
20
+ def self.included(target)
21
+ super
22
+ target.extend ClassMethods
23
+ end
24
+
25
+ def base_element
26
+ return @base_element_proc.call if @base_element_proc
27
+ browser.find_element(:tag_name, 'html')
28
+ end
29
+
30
+ def showing?
31
+ base_element
32
+ true
33
+ rescue Selenium::WebDriver::Error::NoSuchElementError
34
+ false
35
+ end
36
+
37
+ module ClassMethods
38
+
39
+ def base_element(selector, selector_type=:id)
40
+ define_method(:base_element) do
41
+ browser.find_element selector_type, selector
42
+ end
43
+ end
44
+
45
+ def default_selector_type(selector_type)
46
+ @default_selector_type = selector_type
47
+ end
48
+
49
+ # :as options: :auto, :text, :click, :link, :select_by_text, :select_by_value, :hover, :location, :size, :toggle, :value, ViewerClass
50
+ def element(name, selector=name.to_s, options={}, &selector_proc)
51
+ if options.empty? && selector.is_a?(::Hash)
52
+ options = selector
53
+ selector = name
54
+ end
55
+ selector = selector_proc if selector_proc
56
+ selector_type = options[:by] || @default_selector_type || :id
57
+ output_type = options[:as] || :value
58
+
59
+ define_method("#{name}_element_reader") do
60
+ ElementReader.new(self, selector, selector_type)
61
+ end
62
+
63
+ define_method("#{name}_element") do
64
+ send("#{name}_element_reader").get
65
+ end
66
+
67
+ define_method(name) do
68
+ element_reader = send("#{name}_element_reader")
69
+ ElementValueReader.new(element_reader, output_type).get
70
+ end
71
+
72
+ # only define this method if result type suggests assignability
73
+ define_method("#{name}=") do |new_value|
74
+ element_reader = send("#{name}_element_reader")
75
+ raise "parameters required" if element_reader.requires_parameters?
76
+ ElementValueWriter.new(element_reader.get, output_type).value = new_value
77
+ end
78
+
79
+ define_method("#{name}_present?") do |*arguments|
80
+ raise ArgumentError(1, arguments.length) if arguments.length > 1
81
+ timeout = arguments[0].to_f
82
+ element_present? selector_type, selector, timeout
83
+ end
84
+ alias_method "has_#{name}?", "#{name}_present?"
85
+
86
+ end
87
+
88
+ end
89
+
90
+ end
91
+
92
+ class WebViewerObject
93
+ include BrowserInstance
94
+ include WebViewer
95
+ end
96
+
@@ -0,0 +1,53 @@
1
+ require 'selenium-webdriver'
2
+
3
+ module HumaneWebDriverExtensions
4
+ # deal with different html element types:
5
+ # boolean for checkboxes, radio buttons, and individual options in select controls
6
+ # string for inputs, textarea, and selects
7
+ # send JavaScript for hidden inputs?
8
+ def value=(new_value)
9
+ case self.tag_name.to_sym
10
+ when :input, :textarea
11
+ clear
12
+ send_keys new_value.to_s
13
+ else
14
+ raise "cannot set value for a #{self.tag_name} element - only input and textarea supported"
15
+ end
16
+ end
17
+ end
18
+
19
+ module Selenium
20
+ module WebDriver
21
+
22
+ module Find
23
+
24
+ def element_present?(how, what, how_long=0)
25
+ wait_for_element_present(how, what, how_long)
26
+ true
27
+ rescue Selenium::WebDriver::Error::NoSuchElementError
28
+ false
29
+ end
30
+
31
+ def wait_for_element_present(how, what, how_long)
32
+ attempts_left = how_long / 0.1
33
+ begin
34
+ find_element(how, what)
35
+ rescue Selenium::WebDriver::Error::NoSuchElementError
36
+ if attempts_left > 0
37
+ attempts_left -= 1
38
+ sleep 0.1
39
+ retry
40
+ end
41
+ fail
42
+ end
43
+ end
44
+
45
+ end
46
+
47
+ class Element
48
+ include HumaneWebDriverExtensions
49
+ end
50
+
51
+ end
52
+ end
53
+
@@ -0,0 +1,83 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{selenium-webdriver-viewers}
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Michael Collas"]
12
+ s.date = %q{2010-12-16}
13
+ s.description = %q{ This gem makes it easy to create page and web viewer objects for use by tests that use selenium-webdriver. By
14
+ using page and viewer objects, you can decouple your tests from the html details so that they can focus
15
+ instead on describing the behaviour of your application.
16
+ }
17
+ s.email = %q{mcollas@yahoo.com}
18
+ s.extra_rdoc_files = [
19
+ "LICENSE",
20
+ "README.rdoc",
21
+ "TODO"
22
+ ]
23
+ s.files = [
24
+ ".document",
25
+ "LICENSE",
26
+ "README.rdoc",
27
+ "Rakefile",
28
+ "TODO",
29
+ "VERSION",
30
+ "lib/browser-instance.rb",
31
+ "lib/element_reader.rb",
32
+ "lib/element_value_reader.rb",
33
+ "lib/element_value_writer.rb",
34
+ "lib/page.rb",
35
+ "lib/selenium-webdriver-viewers.rb",
36
+ "lib/viewer.rb",
37
+ "lib/webdriver-extensions.rb",
38
+ "selenium-webdriver-viewers.gemspec",
39
+ "spec/browser-instance_spec.rb",
40
+ "spec/element_reader_spec.rb",
41
+ "spec/element_value_reader_spec.rb",
42
+ "spec/element_value_writer_spec.rb",
43
+ "spec/page_spec.rb",
44
+ "spec/selenium-webdriver-viewers_spec.rb",
45
+ "spec/spec.opts",
46
+ "spec/spec_helper.rb",
47
+ "spec/viewer_spec.rb"
48
+ ]
49
+ s.homepage = %q{http://github.com/michaelcollas/selenium-webdriver-viewers}
50
+ s.require_paths = ["lib"]
51
+ s.rubygems_version = %q{1.3.7}
52
+ s.summary = %q{Makes page objects and views for tests using selenium-webdriver.}
53
+ s.test_files = [
54
+ "spec/browser-instance_spec.rb",
55
+ "spec/element_reader_spec.rb",
56
+ "spec/element_value_reader_spec.rb",
57
+ "spec/element_value_writer_spec.rb",
58
+ "spec/page_spec.rb",
59
+ "spec/selenium-webdriver-viewers_spec.rb",
60
+ "spec/spec_helper.rb",
61
+ "spec/viewer_spec.rb"
62
+ ]
63
+
64
+ if s.respond_to? :specification_version then
65
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
66
+ s.specification_version = 3
67
+
68
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
69
+ s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
70
+ s.add_development_dependency(%q<reek>, [">= 1.2.8"])
71
+ s.add_development_dependency(%q<sexp_processor>, [">= 3.0.4"])
72
+ else
73
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
74
+ s.add_dependency(%q<reek>, [">= 1.2.8"])
75
+ s.add_dependency(%q<sexp_processor>, [">= 3.0.4"])
76
+ end
77
+ else
78
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
79
+ s.add_dependency(%q<reek>, [">= 1.2.8"])
80
+ s.add_dependency(%q<sexp_processor>, [">= 3.0.4"])
81
+ end
82
+ end
83
+
@@ -0,0 +1,96 @@
1
+ require 'spec_helper'
2
+
3
+ describe BrowserInstance do
4
+
5
+ describe '#base_url' do
6
+
7
+ before do
8
+ BrowserInstance.base_url = nil
9
+ end
10
+
11
+ after do
12
+ BrowserInstance.base_url = nil
13
+ end
14
+
15
+ it 'should have an empty base url by default' do
16
+ BrowserInstance.base_url.should == ''
17
+ end
18
+
19
+ it 'should have the base url set by base_url=' do
20
+ BrowserInstance.base_url = 'http://something'
21
+ BrowserInstance.base_url.should == 'http://something'
22
+ end
23
+
24
+ it 'should have a base url provided by environment variable if none has been set by base_url=' do
25
+ ENV.stub!(:[]).with('BASE_URL').and_return('http://from-environment')
26
+ BrowserInstance.base_url.should == 'http://from-environment'
27
+ end
28
+
29
+ end
30
+
31
+ describe 'browser_instance' do
32
+
33
+ before do
34
+ @driver = stub('firefox driver')
35
+ class << @driver
36
+ attr_reader :last_to_location
37
+ def to(location)
38
+ @last_to_location = location
39
+ end
40
+ end
41
+ @driver.stub!(:navigate).and_return(@driver)
42
+ Selenium::WebDriver.stub!(:for).and_return(@driver)
43
+ end
44
+
45
+ after do
46
+ BrowserInstance.instance_variable_set(:@browser, nil)
47
+ end
48
+
49
+ it 'should create a new WebDriver driver instance for firefox' do
50
+ Selenium::WebDriver.should_receive(:for).with(:firefox).and_return(@driver)
51
+ BrowserInstance.browser_instance
52
+ end
53
+
54
+ it 'should return the created driver from browser_instance' do
55
+ BrowserInstance.browser_instance.should equal(@driver)
56
+ end
57
+
58
+ describe 'navigate interface' do
59
+
60
+ before do
61
+ BrowserInstance.base_url = 'http://flibble'
62
+ @browser = BrowserInstance.browser_instance
63
+ end
64
+
65
+ it 'should prepend the base url when to is used' do
66
+ @browser.navigate.to '/somewhere'
67
+ @browser.last_to_location.should == 'http://flibble/somewhere'
68
+ end
69
+
70
+ it 'should ignore the base url when navigate.to_absolute is used' do
71
+ @browser.navigate.to_absolute '/somewhere'
72
+ @browser.last_to_location.should == '/somewhere'
73
+ end
74
+
75
+ end
76
+
77
+ describe 'when a browser has already been requested' do
78
+
79
+ before do
80
+ BrowserInstance.browser_instance
81
+ end
82
+
83
+ it 'should not create another WebDriver driver instance' do
84
+ Selenium::WebDriver.should_not_receive(:for)
85
+ BrowserInstance.browser_instance
86
+ end
87
+
88
+ it 'should return the same instance on subsequent calls' do
89
+ BrowserInstance.browser_instance.should equal(BrowserInstance.browser_instance)
90
+ end
91
+
92
+ end
93
+
94
+ end
95
+
96
+ end
@@ -0,0 +1,106 @@
1
+ require 'spec_helper'
2
+
3
+ describe WebViewer::ElementReader do
4
+
5
+ before do
6
+ @dummy_element = stub('webdriver element')
7
+ @viewer = stub('viewer', :find_element => @dummy_element)
8
+ end
9
+
10
+ describe 'when the selector is a proc' do
11
+
12
+ describe 'and the selector proc has parameters' do
13
+
14
+ before do
15
+ @reader = WebViewer::ElementReader.new(@viewer, proc {|argument| "proc based selector with #{argument}"}, :css)
16
+ end
17
+
18
+ it 'should require parameters' do
19
+ @reader.requires_parameters?.should be_true
20
+ end
21
+
22
+ describe '#get' do
23
+
24
+ it 'should return itself if parameters are not provided' do
25
+ @reader.get.should == @reader
26
+ end
27
+
28
+ it 'should fetch the element from the viewer using the result of calling the proc if parameters are provided' do
29
+ @viewer.should_receive(:find_element).with(:css, 'proc based selector with parameter value')
30
+ @reader.get('parameter value')
31
+ end
32
+
33
+ it 'should return the fetched element if parameters are provided' do
34
+ @reader.get('parameter value').should == @dummy_element
35
+ end
36
+
37
+ end
38
+
39
+ describe '#[]' do
40
+
41
+ it 'should fetch the element from the viewer using the result of calling the proc if parameters are provided' do
42
+ @viewer.should_receive(:find_element).with(:css, 'proc based selector with parameter value')
43
+ @reader['parameter value']
44
+ end
45
+
46
+ it 'should return the fetched element if parameters are provided' do
47
+ @reader['parameter value'].should == @dummy_element
48
+ end
49
+
50
+ end
51
+
52
+ end
53
+
54
+ describe 'and the selector proc has no parameters' do
55
+
56
+ before do
57
+ @reader = WebViewer::ElementReader.new(@viewer, proc {'proc based selector'}, :css)
58
+ end
59
+
60
+ it 'should not require parameters if the selector is a proc with no parameters' do
61
+ @reader.requires_parameters?.should be_false
62
+ end
63
+
64
+ it 'should recognize that the selector is callable' do
65
+ @reader.callable_selector?.should be_true
66
+ end
67
+
68
+ it 'should fetch the element from the viewer using the result of calling the proc' do
69
+ @viewer.should_receive(:find_element).with(:css, 'proc based selector')
70
+ @reader.get
71
+ end
72
+
73
+ it 'should return the fetched element' do
74
+ @reader.get.should == @dummy_element
75
+ end
76
+
77
+ end
78
+
79
+ end
80
+
81
+ describe 'when the selector is a string' do
82
+
83
+ before do
84
+ @reader = WebViewer::ElementReader.new(@viewer, 'text based selector', :css)
85
+ end
86
+
87
+ it 'should not require parameters if the selector is a string' do
88
+ @reader.requires_parameters?.should be_false
89
+ end
90
+
91
+ it 'should recognize that the selector is not callable' do
92
+ @reader.callable_selector?.should be_false
93
+ end
94
+
95
+ it 'should fetch the element from the viewer' do
96
+ @viewer.should_receive(:find_element).with(:css, 'text based selector')
97
+ @reader.get
98
+ end
99
+
100
+ it 'should return the fetched element' do
101
+ @reader.get.should == @dummy_element
102
+ end
103
+
104
+ end
105
+
106
+ end
@@ -0,0 +1,161 @@
1
+ require 'spec_helper'
2
+
3
+ describe WebViewer::ElementValueReader do
4
+
5
+ share_as :UnimplementedOutputType do
6
+
7
+ it 'should raise an exception' do
8
+ output_type = self.class.options[:output_type]
9
+ value_reader = WebViewer::ElementValueReader.new(@element_reader, output_type)
10
+ read_operation = lambda { @element_reader.requires_parameters? ? value_reader['1'] : value_reader.get }
11
+ read_operation.should raise_error "not yet implemented"
12
+ end
13
+
14
+ end
15
+
16
+ describe 'when the element reader does not require parameters' do
17
+
18
+ before do
19
+ @dummy_element = stub(:value => 'element value')
20
+ @element_reader = stub('element reader', :requires_parameters? => false, :get => @dummy_element)
21
+ end
22
+
23
+ describe 'and the output type is not a class' do
24
+
25
+ before do
26
+ @value_reader = WebViewer::ElementValueReader.new(@element_reader, :value)
27
+ end
28
+
29
+ describe '#get' do
30
+
31
+ it 'should fetch the element from the element reader' do
32
+ @element_reader.should_receive(:get).and_return(@dummy_element)
33
+ @value_reader.get
34
+ end
35
+
36
+ it 'should call the method on the element with name equal to the output type parameter' do
37
+ @dummy_element.should_receive(:value)
38
+ @value_reader.get
39
+ end
40
+
41
+ it 'should return the result of calling the method on the element with name equal to the output type parameter' do
42
+ @value_reader.get.should == 'element value'
43
+ end
44
+
45
+ end
46
+
47
+ end
48
+
49
+ describe ('and the type is :auto', :output_type => :auto) { it_should_behave_like UnimplementedOutputType }
50
+ describe ('and the type is :link', :output_type => :link) { it_should_behave_like UnimplementedOutputType }
51
+ describe ('and the type is :select_by_text', :output_type => :select_by_text) { it_should_behave_like UnimplementedOutputType }
52
+ describe ('and the type is :select_by_value', :output_type => :select_by_value) { it_should_behave_like UnimplementedOutputType }
53
+
54
+ describe 'and the output type is a class' do
55
+
56
+ class FakeViewer
57
+ attr :base_element_proc
58
+ end
59
+
60
+ before do
61
+ @value_reader = WebViewer::ElementValueReader.new(@element_reader, FakeViewer)
62
+ end
63
+
64
+ it 'should return an instance of the specified class' do
65
+ @value_reader.get.should be_instance_of(FakeViewer)
66
+ end
67
+
68
+ it 'should put a base_element_proc instance value into the returned object' do
69
+ @value_reader.get.base_element_proc.should_not be_nil
70
+ end
71
+
72
+ end
73
+
74
+ end
75
+
76
+ describe 'when the element reader requires parameters' do
77
+
78
+ before do
79
+ @dummy_element = stub(:value => 'element value')
80
+ @element_reader = stub('element reader', :requires_parameters? => true, :get => @dummy_element)
81
+ end
82
+
83
+ describe 'and the output type is not a class' do
84
+
85
+ before do
86
+ @value_reader = WebViewer::ElementValueReader.new(@element_reader, :value)
87
+ end
88
+
89
+ it '#get should return the element value reader' do
90
+ @value_reader.get.should == @value_reader
91
+ end
92
+
93
+ describe '#[]' do
94
+
95
+ it 'should fetch the element from the element reader passing provided parameters' do
96
+ @element_reader.should_receive(:get).with(1, 2, 3).and_return(@dummy_element)
97
+ @value_reader[1, 2, 3]
98
+ end
99
+
100
+ it 'should call the method on the element with name equal to the output type parameter' do
101
+ @dummy_element.should_receive(:value)
102
+ @value_reader[1]
103
+ end
104
+
105
+ it 'should return the result of calling the method on the element with name equal to the output type parameter' do
106
+ @value_reader[1].should == 'element value'
107
+ end
108
+
109
+ end
110
+
111
+ describe '#[]=' do
112
+
113
+ before do
114
+ @fake_value_writer = stub(:value= => nil)
115
+ WebViewer::ElementValueWriter.stub(:new).and_return(@fake_value_writer)
116
+ end
117
+
118
+ it 'should get the element from the element reader using all parameters except the assigned value' do
119
+ @element_reader.should_receive(:get).with(1, 2, 3).and_return(@dummy_element)
120
+ @value_reader[1, 2, 3] = 4
121
+ end
122
+
123
+ it 'should create an element value writer with the element and output type' do
124
+ WebViewer::ElementValueWriter.should_receive(:new).with(@dummy_element, :value)
125
+ @value_reader[1, 2, 3] = 4
126
+ end
127
+
128
+ it 'should assign the value to the writer using value=' do
129
+ @fake_value_writer.should_receive(:value=).with(4)
130
+ @value_reader[1, 2, 3] = 4
131
+ end
132
+
133
+ end
134
+
135
+ end
136
+
137
+ describe ('and the type is :auto', :output_type => :auto) { it_should_behave_like UnimplementedOutputType }
138
+ describe ('and the type is :link', :output_type => :link) { it_should_behave_like UnimplementedOutputType }
139
+ describe ('and the type is :select_by_text', :output_type => :select_by_text) { it_should_behave_like UnimplementedOutputType }
140
+ describe ('and the type is :select_by_value', :output_type => :select_by_value) { it_should_behave_like UnimplementedOutputType }
141
+
142
+ describe 'and the output type is a class' do
143
+
144
+ before do
145
+ @value_reader = WebViewer::ElementValueReader.new(@element_reader, FakeViewer)
146
+ end
147
+
148
+ it 'should return an instance of the specified class' do
149
+ @value_reader[1, 2].should be_instance_of(FakeViewer)
150
+ end
151
+
152
+ it 'should put a base_element_proc instance value that gets the element from the reader into the returned object' do
153
+ @element_reader.should_receive(:get).with(1, 2)
154
+ @value_reader[1, 2].base_element_proc.call
155
+ end
156
+
157
+ end
158
+
159
+ end
160
+
161
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe WebViewer::ElementValueWriter do
4
+
5
+ describe "#value=" do
6
+
7
+ it 'should assign the new value to its web element using value=' do
8
+ web_element = stub('WebDriver::Element')
9
+ writer = WebViewer::ElementValueWriter.new(web_element, :value)
10
+ web_element.should_receive(:value=).with('new value')
11
+ writer.value = 'new value'
12
+ end
13
+
14
+ end
15
+
16
+ end
data/spec/page_spec.rb ADDED
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'an object that includes WebPage' do
4
+
5
+ class SampleWebPage
6
+ include WebPage
7
+ end
8
+
9
+ before do
10
+ @page = SampleWebPage.new
11
+ @page.stub!(:navigate).and_return(stub('navigate interface'))
12
+ end
13
+
14
+ it 'should not have a url instance method if the url class method has not been called' do
15
+ @page.respond_to?(:url).should == false
16
+ end
17
+
18
+ it 'should not have a path instance method if the path class method has not been called' do
19
+ @page.respond_to?(:path).should == false
20
+ end
21
+
22
+ describe 'with a url set using the .url class method' do
23
+
24
+ before do
25
+ class << @page
26
+ url 'http://somewhere'
27
+ end
28
+ end
29
+
30
+ it 'should return the value from #url that was set by .url' do
31
+ @page.url.should == 'http://somewhere'
32
+ end
33
+
34
+ it 'should navigate to the absolute url when load is called' do
35
+ @page.navigate.should_receive(:to_absolute).with('http://somewhere')
36
+ @page.load
37
+ end
38
+
39
+ end
40
+
41
+ describe 'with a url set using the .url class method' do
42
+
43
+ before do
44
+ class << @page
45
+ path '/somewhere'
46
+ end
47
+ end
48
+
49
+ it 'should return the value from #path that was set by .path' do
50
+ @page.path.should == '/somewhere'
51
+ end
52
+
53
+ it 'should navigate to the relative path when load is called' do
54
+ @page.navigate.should_receive(:to_relative).with('/somewhere')
55
+ @page.load
56
+ end
57
+
58
+ end
59
+
60
+ it 'should construct itself and call #load when .load is called' do
61
+ SampleWebPage.stub!(:new).and_return(@page)
62
+ @page.should_receive(:load)
63
+ SampleWebPage.load
64
+ end
65
+
66
+ end
@@ -0,0 +1,4 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "SeleniumWebdriverViewers" do
4
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --format specdoc
@@ -0,0 +1,10 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'rubygems'
4
+ require 'selenium-webdriver-viewers'
5
+ require 'spec'
6
+ require 'spec/autorun'
7
+
8
+ Spec::Runner.configure do |config|
9
+
10
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe WebViewer, 'included in a class' do
4
+
5
+ before do
6
+ @viewer_class = Class.new(Object).extend(WebViewer)
7
+ end
8
+
9
+ end
metadata ADDED
@@ -0,0 +1,146 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: selenium-webdriver-viewers
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Michael Collas
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-12-16 00:00:00 +11:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rspec
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 13
30
+ segments:
31
+ - 1
32
+ - 2
33
+ - 9
34
+ version: 1.2.9
35
+ type: :development
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: reek
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 15
46
+ segments:
47
+ - 1
48
+ - 2
49
+ - 8
50
+ version: 1.2.8
51
+ type: :development
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: sexp_processor
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 15
62
+ segments:
63
+ - 3
64
+ - 0
65
+ - 4
66
+ version: 3.0.4
67
+ type: :development
68
+ version_requirements: *id003
69
+ description: " This gem makes it easy to create page and web viewer objects for use by tests that use selenium-webdriver. By\n using page and viewer objects, you can decouple your tests from the html details so that they can focus\n instead on describing the behaviour of your application. \n"
70
+ email: mcollas@yahoo.com
71
+ executables: []
72
+
73
+ extensions: []
74
+
75
+ extra_rdoc_files:
76
+ - LICENSE
77
+ - README.rdoc
78
+ - TODO
79
+ files:
80
+ - .document
81
+ - LICENSE
82
+ - README.rdoc
83
+ - Rakefile
84
+ - TODO
85
+ - VERSION
86
+ - lib/browser-instance.rb
87
+ - lib/element_reader.rb
88
+ - lib/element_value_reader.rb
89
+ - lib/element_value_writer.rb
90
+ - lib/page.rb
91
+ - lib/selenium-webdriver-viewers.rb
92
+ - lib/viewer.rb
93
+ - lib/webdriver-extensions.rb
94
+ - selenium-webdriver-viewers.gemspec
95
+ - spec/browser-instance_spec.rb
96
+ - spec/element_reader_spec.rb
97
+ - spec/element_value_reader_spec.rb
98
+ - spec/element_value_writer_spec.rb
99
+ - spec/page_spec.rb
100
+ - spec/selenium-webdriver-viewers_spec.rb
101
+ - spec/spec.opts
102
+ - spec/spec_helper.rb
103
+ - spec/viewer_spec.rb
104
+ has_rdoc: true
105
+ homepage: http://github.com/michaelcollas/selenium-webdriver-viewers
106
+ licenses: []
107
+
108
+ post_install_message:
109
+ rdoc_options: []
110
+
111
+ require_paths:
112
+ - lib
113
+ required_ruby_version: !ruby/object:Gem::Requirement
114
+ none: false
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ hash: 3
119
+ segments:
120
+ - 0
121
+ version: "0"
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ hash: 3
128
+ segments:
129
+ - 0
130
+ version: "0"
131
+ requirements: []
132
+
133
+ rubyforge_project:
134
+ rubygems_version: 1.3.7
135
+ signing_key:
136
+ specification_version: 3
137
+ summary: Makes page objects and views for tests using selenium-webdriver.
138
+ test_files:
139
+ - spec/browser-instance_spec.rb
140
+ - spec/element_reader_spec.rb
141
+ - spec/element_value_reader_spec.rb
142
+ - spec/element_value_writer_spec.rb
143
+ - spec/page_spec.rb
144
+ - spec/selenium-webdriver-viewers_spec.rb
145
+ - spec/spec_helper.rb
146
+ - spec/viewer_spec.rb