interactor_ui_automation 0.1.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8eb60bd9a431460b2d5ead835e28487843b1316d
4
+ data.tar.gz: dcdee02fc1199bce9971403c5ae3cebb38b3a6d9
5
+ SHA512:
6
+ metadata.gz: 9cd1d27fb588641291d548210ceb8e69e81da82976d58044d3946e143f6b6893f7e22a0824c8160fad6487b7ff4916a73a5c1772b475c27791c4dcc6520f9878
7
+ data.tar.gz: 06a2dca45094893e8d56c68623de3a6b602eb6a865492ad4b30bc0fdc4821cb204a32bd8adc47b6bb87fd0d75f9c41d109ed8fd54d655a186a7c7fed81696458
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in interactor_ui_automation.gemspec
4
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "interactor_ui_automation"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,36 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'interactor_ui_automation/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "interactor_ui_automation"
8
+ spec.version = InteractorUIAutomation::VERSION
9
+ spec.authors = ["Kevin Rood"]
10
+ spec.email = ["kevin.rood@accelecode.com"]
11
+
12
+ spec.summary = %q{Write selenium-webdriver browser automation using a series of conventions.}
13
+ spec.description = %q{Write selenium-webdriver browser automation using a series of conventions.}
14
+ spec.homepage = "https://github.com/accelecode/interactor_ui_test_automation"
15
+ spec.license = "Apache-2.0"
16
+
17
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
18
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
19
+ if spec.respond_to?(:metadata)
20
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
21
+ else
22
+ raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
23
+ end
24
+
25
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
26
+ f.match(%r{^(test|spec|features)/})
27
+ end
28
+ spec.bindir = "exe"
29
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
30
+ spec.require_paths = ["lib"]
31
+
32
+ spec.add_development_dependency "bundler", "~> 1.13"
33
+ spec.add_development_dependency "rake", "~> 10.0"
34
+
35
+ spec.add_dependency "selenium-webdriver", "~> 2.52"
36
+ end
@@ -0,0 +1,17 @@
1
+ module InteractorUIAutomation module Interactor class ActionInteractor < BaseInteractor
2
+
3
+ def initialize(driver, name, xpath_root='//*')
4
+ super
5
+ end
6
+
7
+ def activate
8
+ find_element.click
9
+ end
10
+
11
+ private
12
+
13
+ def current_xpath
14
+ "#{@xpath_root}//*[@data-action='#{@name}']"
15
+ end
16
+
17
+ end end end
@@ -0,0 +1,43 @@
1
+ require 'selenium-webdriver'
2
+
3
+ module InteractorUIAutomation module Interactor class BaseInteractor
4
+
5
+ def initialize(driver, name=nil, xpath_root='//*')
6
+ @driver = driver
7
+ @name = name
8
+ @xpath_root = xpath_root
9
+ end
10
+
11
+ def is_visible!
12
+ wait.until { @driver.find_element(xpath: current_xpath).displayed? }
13
+ rescue
14
+ raise("xpath is not visible: #{current_xpath}")
15
+ end
16
+
17
+ def is_not_visible!
18
+ wait.until do
19
+ elements = @driver.find_elements(xpath: current_xpath)
20
+ elements.count == 0 || elements.map(&:displayed?).none?
21
+ end
22
+ rescue
23
+ raise("xpath is visible: #{current_xpath}")
24
+ end
25
+
26
+ private
27
+
28
+ def current_xpath
29
+ raise('Subclass must override method')
30
+ end
31
+
32
+ def wait
33
+ Selenium::WebDriver::Wait.new(timeout: 5, interval: 0.2)
34
+ end
35
+
36
+ def find_element
37
+ is_visible!
38
+
39
+ wait = Selenium::WebDriver::Wait.new(timeout: 5, interval: 0.2)
40
+ wait.until { @driver.find_element(xpath: current_xpath) }
41
+ end
42
+
43
+ end end end
@@ -0,0 +1,33 @@
1
+ module InteractorUIAutomation module Interactor class CheckboxFieldInteractor < BaseInteractor
2
+
3
+ def initialize(driver, name, xpath_root='//*')
4
+ super
5
+ end
6
+
7
+ def is_checked!
8
+ wait.until { find_element.selected? }
9
+ end
10
+
11
+ def is_not_checked!
12
+ wait.until { find_element.selected? == false }
13
+ end
14
+
15
+ def check
16
+ find_element.tap do |element|
17
+ element.click unless element.selected?
18
+ end
19
+ end
20
+
21
+ def uncheck
22
+ find_element.tap do |element|
23
+ element.click if element.selected?
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ def current_xpath
30
+ "#{@xpath_root}//*[@name='#{@name}']"
31
+ end
32
+
33
+ end end end
@@ -0,0 +1,38 @@
1
+ module InteractorUIAutomation module Interactor class DropdownFieldInteractor < BaseInteractor
2
+
3
+ def initialize(driver, name, xpath_root='//*')
4
+ super
5
+ end
6
+
7
+ def option_is_selected!(option_name)
8
+ wait.until { find_element.first_selected_option.text == option_name }
9
+ end
10
+
11
+ def option_is_not_selected!(option_name)
12
+ wait.until { find_element.first_selected_option.text != option_name }
13
+ end
14
+
15
+ def empty_option_is_selected!
16
+ option_is_selected!('')
17
+ end
18
+
19
+ def select_option(option_name)
20
+ find_element.select_by(:text, option_name)
21
+ end
22
+
23
+ def select_empty_option
24
+ select_option('')
25
+ end
26
+
27
+ private
28
+
29
+ def current_xpath
30
+ "#{@xpath_root}//*[@name='#{@name}']"
31
+ end
32
+
33
+ def find_element
34
+ element = super
35
+ Selenium::WebDriver::Support::Select.new(element)
36
+ end
37
+
38
+ end end end
@@ -0,0 +1,21 @@
1
+ module InteractorUIAutomation module Interactor class ElementInteractor < BaseInteractor
2
+
3
+ def initialize(driver, name, xpath_root='//*')
4
+ super
5
+ end
6
+
7
+ def has_text!(text)
8
+ wait.until { find_element.text == text }
9
+ end
10
+
11
+ def does_not_have_text!(text)
12
+ wait.until { find_element.text != text }
13
+ end
14
+
15
+ private
16
+
17
+ def current_xpath
18
+ "#{@xpath_root}//*[@data-element='#{@name}']"
19
+ end
20
+
21
+ end end end
@@ -0,0 +1,17 @@
1
+ module InteractorUIAutomation module Interactor class ListInteractor < BaseInteractor
2
+
3
+ def initialize(driver, name, xpath_root='//*')
4
+ super
5
+ end
6
+
7
+ def row(selector_options)
8
+ RowInteractor.new(@driver, selector_options, current_xpath)
9
+ end
10
+
11
+ private
12
+
13
+ def current_xpath
14
+ "#{@xpath_root}//*[@data-view='#{@name}']"
15
+ end
16
+
17
+ end end end
@@ -0,0 +1,19 @@
1
+ module InteractorUIAutomation module Interactor class RowInteractor < ViewInteractor
2
+
3
+ def initialize(driver, selector_options, xpath_root='//*')
4
+ super(driver, nil, xpath_root)
5
+ @selector_options = selector_options
6
+ end
7
+
8
+ private
9
+
10
+ def current_xpath
11
+ elements = @selector_options.fetch(:elements)
12
+ # row selector looks like this:
13
+ # "//*[@data-element='firstName' and normalize-space(text())='John']//ancestor::*[@data-view='row']//*[@data-element='lastName' and normalize-space(text())='Miller']//ancestor::*[@data-view='row']"
14
+ # The generated xpath traverses down into the row and then back up to the row element itself
15
+ row_selector = elements.map { |key, value| "//*[@data-element='#{key}' and normalize-space(text())='#{value}']//ancestor::*[@data-view='row']" }.join
16
+ "#{@xpath_root}//*[@data-view='row']#{row_selector}"
17
+ end
18
+
19
+ end end end
@@ -0,0 +1,36 @@
1
+ module InteractorUIAutomation module Interactor class TextFieldInteractor < BaseInteractor
2
+
3
+ def initialize(driver, name, xpath_root='//*')
4
+ super
5
+ end
6
+
7
+ def has_text!(text)
8
+ wait.until { find_element.attribute('value') == text }
9
+ end
10
+
11
+ def does_not_have_text!(text)
12
+ wait.until { find_element.attribute('value') != text }
13
+ end
14
+
15
+ def is_blank!
16
+ has_text!('')
17
+ end
18
+
19
+ def enter_text(text)
20
+ find_element.tap do |element|
21
+ element.clear
22
+ element.send_keys(text)
23
+ end
24
+ end
25
+
26
+ def clear_text
27
+ find_element.clear
28
+ end
29
+
30
+ private
31
+
32
+ def current_xpath
33
+ "#{@xpath_root}//*[@name='#{@name}']"
34
+ end
35
+
36
+ end end end
@@ -0,0 +1,41 @@
1
+ module InteractorUIAutomation module Interactor class ViewInteractor < BaseInteractor
2
+
3
+ def initialize(driver, name=nil, xpath_root='//*')
4
+ super
5
+ end
6
+
7
+ def view(name)
8
+ ViewInteractor.new(@driver, name, current_xpath)
9
+ end
10
+
11
+ def action(name)
12
+ ActionInteractor.new(@driver, name, current_xpath)
13
+ end
14
+
15
+ def element(name)
16
+ ElementInteractor.new(@driver, name, current_xpath)
17
+ end
18
+
19
+ def list(name)
20
+ ListInteractor.new(@driver, name, current_xpath)
21
+ end
22
+
23
+ def text_field(name)
24
+ TextFieldInteractor.new(@driver, name, current_xpath)
25
+ end
26
+
27
+ def dropdown_field(name)
28
+ DropdownFieldInteractor.new(@driver, name, current_xpath)
29
+ end
30
+
31
+ def checkbox_field(name)
32
+ CheckboxFieldInteractor.new(@driver, name, current_xpath)
33
+ end
34
+
35
+ private
36
+
37
+ def current_xpath
38
+ (@name ? "#{@xpath_root}//*[@data-view='#{@name}']" : @xpath_root)
39
+ end
40
+
41
+ end end end
@@ -0,0 +1,9 @@
1
+ require_relative 'interactor/base_interactor'
2
+ require_relative 'interactor/action_interactor'
3
+ require_relative 'interactor/element_interactor'
4
+ require_relative 'interactor/text_field_interactor'
5
+ require_relative 'interactor/dropdown_field_interactor'
6
+ require_relative 'interactor/checkbox_field_interactor'
7
+ require_relative 'interactor/view_interactor'
8
+ require_relative 'interactor/list_interactor'
9
+ require_relative 'interactor/row_interactor'
@@ -0,0 +1,23 @@
1
+ require 'minitest/autorun'
2
+ require 'forwardable'
3
+ require 'selenium-webdriver'
4
+ require 'interactor_ui_automation'
5
+
6
+ module InteractorUIAutomation class InteractorTest < Minitest::Test
7
+ extend Forwardable
8
+
9
+ attr_reader :driver, :root_view
10
+
11
+ def setup
12
+ super
13
+ @driver = provide_driver
14
+ @root_view = InteractorUIAutomation::Interactor::ViewInteractor.new(@driver)
15
+ end
16
+
17
+ def_delegators :root_view, :view, :action, :element, :list, :text_field, :dropdown_field, :checkbox_field
18
+
19
+ def provide_driver
20
+ raise('Subclass must define `#provide_driver()`')
21
+ end
22
+
23
+ end end
@@ -0,0 +1,3 @@
1
+ module InteractorUIAutomation
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,2 @@
1
+ require_relative 'interactor_ui_automation/version'
2
+ require_relative 'interactor_ui_automation/interactor'
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: interactor_ui_automation
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Kevin Rood
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-03-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.13'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.13'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: selenium-webdriver
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.52'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.52'
55
+ description: Write selenium-webdriver browser automation using a series of conventions.
56
+ email:
57
+ - kevin.rood@accelecode.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - Gemfile
64
+ - Rakefile
65
+ - bin/console
66
+ - bin/setup
67
+ - interactor_ui_automation.gemspec
68
+ - lib/interactor_ui_automation.rb
69
+ - lib/interactor_ui_automation/interactor.rb
70
+ - lib/interactor_ui_automation/interactor/action_interactor.rb
71
+ - lib/interactor_ui_automation/interactor/base_interactor.rb
72
+ - lib/interactor_ui_automation/interactor/checkbox_field_interactor.rb
73
+ - lib/interactor_ui_automation/interactor/dropdown_field_interactor.rb
74
+ - lib/interactor_ui_automation/interactor/element_interactor.rb
75
+ - lib/interactor_ui_automation/interactor/list_interactor.rb
76
+ - lib/interactor_ui_automation/interactor/row_interactor.rb
77
+ - lib/interactor_ui_automation/interactor/text_field_interactor.rb
78
+ - lib/interactor_ui_automation/interactor/view_interactor.rb
79
+ - lib/interactor_ui_automation/minitest/interactor_test.rb
80
+ - lib/interactor_ui_automation/version.rb
81
+ homepage: https://github.com/accelecode/interactor_ui_test_automation
82
+ licenses:
83
+ - Apache-2.0
84
+ metadata:
85
+ allowed_push_host: https://rubygems.org
86
+ post_install_message:
87
+ rdoc_options: []
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ requirements: []
101
+ rubyforge_project:
102
+ rubygems_version: 2.6.8
103
+ signing_key:
104
+ specification_version: 4
105
+ summary: Write selenium-webdriver browser automation using a series of conventions.
106
+ test_files: []