rutl 0.3.0 → 0.4.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.
@@ -1,32 +1,34 @@
1
1
  require 'selenium-webdriver'
2
2
  require 'rutl/interface/base_interface'
3
3
 
4
- #
5
- # Small interface for Chrome browser.
6
- #
7
- class ChromeInterface < BaseInterface
8
- # rubocop:disable Metrics/MethodLength
9
- def initialize
10
- @logged_in = true
11
- options = Selenium::WebDriver::Chrome::Options.new
12
- options.add_argument('--ignore-certificate-errors')
13
- options.add_argument('--disable-popup-blocking')
14
- options.add_argument('--disable-translate')
15
- # Run headless on TravisCI
16
- if ENV['TRAVIS'] == 'true'
17
- options.add_argument('--disable-gpu')
18
- options.add_argument('--headless ')
19
- options.add_argument('--no-sandbox')
4
+ module RUTL
5
+ #
6
+ # Small interface for Chrome browser.
7
+ #
8
+ class ChromeInterface < BaseInterface
9
+ # rubocop:disable Metrics/MethodLength
10
+ def initialize
11
+ @logged_in = true
12
+ options = Selenium::WebDriver::Chrome::Options.new
13
+ options.add_argument('--ignore-certificate-errors')
14
+ options.add_argument('--disable-popup-blocking')
15
+ options.add_argument('--disable-translate')
16
+ # Run headless on TravisCI
17
+ if ENV['TRAVIS'] == 'true'
18
+ options.add_argument('--disable-gpu')
19
+ options.add_argument('--headless ')
20
+ options.add_argument('--no-sandbox')
21
+ end
22
+ @driver = Selenium::WebDriver.for :chrome, options: options
23
+ super
20
24
  end
21
- @driver = Selenium::WebDriver.for :chrome, options: options
22
- super
23
- end
24
- # rubocop:enable Metrics/MethodLength
25
+ # rubocop:enable Metrics/MethodLength
25
26
 
26
- def current_page
27
- url = @driver.current_url
28
- page = find_page(url)
29
- raise "PAGE NOT FOUND: #{url}, PAGES: #{@pages}" unless page
30
- page
27
+ def current_page
28
+ url = @driver.current_url
29
+ page = find_page(url)
30
+ raise "PAGE NOT FOUND: #{url}, PAGES: #{@pages}" unless page
31
+ page
32
+ end
31
33
  end
32
34
  end
@@ -1,25 +1,27 @@
1
1
  require 'selenium-webdriver'
2
2
  require 'rutl/interface/base_interface'
3
3
 
4
- #
5
- # Small interface for Chrome browser.
6
- #
7
- class FirefoxInterface < BaseInterface
8
- def initialize
9
- @logged_in = true
10
- options = Selenium::WebDriver::Firefox::Options.new
11
- options.add_argument('--ignore-certificate-errors')
12
- options.add_argument('--disable-popup-blocking')
13
- options.add_argument('--disable-translate')
14
- options.add_argument('--headless') if ENV['TRAVIS'] == 'true'
15
- @driver = Selenium::WebDriver.for :firefox, options: options
16
- super
17
- end
4
+ module RUTL
5
+ #
6
+ # Small interface for Chrome browser.
7
+ #
8
+ class FirefoxInterface < BaseInterface
9
+ def initialize
10
+ @logged_in = true
11
+ options = Selenium::WebDriver::Firefox::Options.new
12
+ options.add_argument('--ignore-certificate-errors')
13
+ options.add_argument('--disable-popup-blocking')
14
+ options.add_argument('--disable-translate')
15
+ options.add_argument('--headless') if ENV['TRAVIS'] == 'true'
16
+ @driver = Selenium::WebDriver.for :firefox, options: options
17
+ super
18
+ end
18
19
 
19
- def current_page
20
- url = @driver.current_url
21
- page = find_page(url)
22
- raise "PAGE NOT FOUND: #{url}, PAGES: #{@pages}" unless page
23
- page
20
+ def current_page
21
+ url = @driver.current_url
22
+ page = find_page(url)
23
+ raise "PAGE NOT FOUND: #{url}, PAGES: #{@pages}" unless page
24
+ page
25
+ end
24
26
  end
25
27
  end
@@ -1,31 +1,33 @@
1
1
  require 'rutl/interface/base_interface'
2
2
 
3
- #
4
- # Interface-level code for fake browser.
5
- #
6
- class NullInterface < BaseInterface
7
- def initialize
8
- context = ElementContext.new(destinations: nil,
9
- interface: self,
10
- selectors: [])
11
- @driver = NullDriver.new(context)
12
- super
13
- end
3
+ module RUTL
4
+ #
5
+ # Interface-level code for fake browser.
6
+ #
7
+ class NullInterface < BaseInterface
8
+ def initialize
9
+ context = RUTL::Element::ElementContext.new(destinations: nil,
10
+ interface: self,
11
+ selectors: [])
12
+ @driver = NullDriver.new(context)
13
+ super
14
+ end
14
15
 
15
- # The null driver needs to talk to the null interface.
16
- # Other driver/interface relations are not like this.
17
- attr_writer :current_page
16
+ # The null driver needs to talk to the null interface.
17
+ # Other driver/interface relations are not like this.
18
+ attr_writer :current_page
18
19
 
19
- def current_page
20
- # Default to @pages.first if not set?
21
- # A browser can always check its current URL but the null driver can't.
22
- @current_page ||= @pages.first
23
- end
20
+ def current_page
21
+ # Default to @pages.first if not set?
22
+ # A browser can always check its current URL but the null driver can't.
23
+ @current_page ||= @pages.first
24
+ end
24
25
 
25
- def wait_for_transition(destinations)
26
- # TODO: Setting @current page didn't do it beacause that set
27
- # context.interface.current_page and we wanted this in the browser.
28
- @current_page = destinations.first.new(self)
29
- $browser.current_page = @current_page
26
+ def wait_for_transition(destinations)
27
+ # TODO: Setting @current page didn't do it beacause that set
28
+ # context.interface.current_page and we wanted this in the browser.
29
+ @current_page = destinations.first.new(self)
30
+ $browser.current_page = @current_page
31
+ end
30
32
  end
31
33
  end
@@ -0,0 +1,42 @@
1
+ require 'rutl/null_driver/null_element'
2
+
3
+ module RUTL
4
+ #
5
+ # This is at a peer level to the webdrivers but it's for a fake brwoser.
6
+ #
7
+ class NullDriver
8
+ attr_accessor :context
9
+
10
+ def initialize(context)
11
+ raise 'no context' unless context.is_a?(RUTL::Element::ElementContext)
12
+ @context = context
13
+ end
14
+
15
+ # Return a new one of these fake things so that it can be clicked
16
+ # ar written to or whatever.
17
+ def find_element(type, location)
18
+ context = RUTL::Element::ElementContext.new(interface: @context.interface)
19
+ RUTL::Element::NullElement.new(context, type, location)
20
+ end
21
+
22
+ # Cheap way to handle browser.navigate.to(url)
23
+ # TODO: Until I care about the url and then I should ????
24
+ def navigate
25
+ context = RUTL::Element::ElementContext.new(interface: @context.interface)
26
+ NullDriver.new(context)
27
+ end
28
+
29
+ # Cheap second part to naviate.to(url) calls to look like real drivers.
30
+ def to(url)
31
+ result = @context.interface.find_page(url)
32
+ @context.interface.current_page = result
33
+ result.url
34
+ end
35
+
36
+ # Clean out the @@variables from NullElement.
37
+ # Other than this, this is a placeholder to match real drivers.
38
+ def quit
39
+ RUTL::Element::NullElement.clear_variables
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,56 @@
1
+ require 'rutl/element/element_context'
2
+
3
+ module RUTL
4
+ module Element
5
+ #
6
+ # This fakes all page elements when used with the null driver.
7
+ # It's a dirty way to avoid modeling all of what a driver talks to.
8
+ #
9
+ class NullElement
10
+ attr_accessor :context
11
+
12
+ def self.clear_variables
13
+ @@variables = {}
14
+ end
15
+
16
+ def initialize(context, _type, location)
17
+ @@variables ||= {}
18
+ @context = context
19
+ @location = location
20
+ end
21
+
22
+ # @@string is a class variable because this framework creates new
23
+ # instances of each element every time it accesses them. This is good
24
+ # behavior by default because pages could change underneath us.
25
+ # For text fields in the null browser, though, we want to preserve the
26
+ # values across calls, letting us write and then read.
27
+ def send_keys(string)
28
+ init = @@variables[@location] || ''
29
+ @@variables[@location] = init + string
30
+ end
31
+
32
+ def attribute(attr)
33
+ case attr.to_sym
34
+ when :value
35
+ @@variables[@location] || ''
36
+ else
37
+ raise ArgumentError, "Attribute unknown: #{attr}"
38
+ end
39
+ end
40
+
41
+ def clear
42
+ @@variables[@location] = ''
43
+ end
44
+
45
+ def this_css
46
+ self
47
+ end
48
+
49
+ # Placeholder - NOP
50
+ # Called by RUTL::Element::ClickToChangeStateMixin like
51
+ # Selenium driver.click
52
+ def click
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,119 @@
1
+ require 'rutl/element'
2
+ require 'rutl/null_driver/null_driver'
3
+
4
+ module RUTL
5
+ #
6
+ # Base page class. It's used to call the magical method_messing
7
+ # stuff to parse the page object files into actual objects.
8
+ #
9
+ class Page
10
+ # BUGBUG: Kludgy. What do I really want to do here?
11
+ # Make it easy to define a page's default url and
12
+ # also matchers for page urls for pages with variable urls?
13
+ # rubocop:disable Style/TrivialAccessors
14
+ def self.url
15
+ @url
16
+ end
17
+
18
+ def url
19
+ self.class.url
20
+ end
21
+ # rubocop:enable Style/TrivialAccessors
22
+
23
+ # Intentially use a class variable to hald pages. Once they're all loaded
24
+ # they are all loaded for everyone.
25
+ # rubocop:disable Style/ClassVars
26
+ @@loaded_pages = []
27
+ # rubocop:enable Style/ClassVars
28
+
29
+ def initialize(interface)
30
+ @interface = interface
31
+ # Dirty trick because we're loading all of page classes from files and
32
+ # then initializing them, calling their layout methods to do magic.
33
+ # The Page class knows what pages are loaded.
34
+ return if @@loaded_pages.include?(self.class)
35
+ layout
36
+ @@loaded_pages << self.class
37
+ end
38
+
39
+ def go_to_here
40
+ # Ovveride this in base page to have something more
41
+ # complicated than this.
42
+ @interface.driver.navigate.to(url)
43
+ end
44
+
45
+ # Written by Browser and only used internally.
46
+ attr_writer :interface
47
+
48
+ def loaded?
49
+ url == @interface.driver.current_url
50
+ end
51
+
52
+ # Dynamically add a method, :<name> (or :<name>= if setter)
53
+ # to the current class where that method creates an instance
54
+ # of klass.
55
+ # context is a RUTL::Element::ElementContext
56
+ #
57
+ # As it is, this seems silly to break into pieces for Rubocop.
58
+ # rubocop:disable Metrics/MethodLength
59
+ def add_method(context:, klass:, name:, setter: false)
60
+ name = "#{name}_#{klass.downcase}"
61
+ constant = Module.const_get("RUTL::Element::#{klass.capitalize}")
62
+ self.class.class_exec do
63
+ if setter
64
+ define_method("#{name}=") do |value|
65
+ constant.new(context, value)
66
+ end
67
+ else
68
+ define_method(name) do
69
+ constant.new(context)
70
+ end
71
+ end
72
+ end
73
+ end
74
+ private :add_method
75
+ # rubocop:enable Metrics/MethodLength
76
+
77
+ # This creates a new element instance whenever it's called.
78
+ # Because of that we can't keep state in any element objects.
79
+ # That seems like a good thing, actually.
80
+ # Called by layout method on pages.
81
+ #
82
+ # Hard to make shorter.
83
+ # rubocop:disable Metrics/MethodLength
84
+ def method_missing(element, *args, &_block)
85
+ name, selectors, rest = args
86
+ context = RUTL::Element::ElementContext.new(destinations: rest,
87
+ interface: @interface,
88
+ selectors: selectors)
89
+ case element
90
+ when /button/, /checkbox/, /element/, /link/
91
+ add_method(name: name, context: context, klass: element)
92
+ when /text/
93
+ add_method(name: name, context: context, klass: element)
94
+ add_method(name: name, context: context, klass: element, setter: true)
95
+ else
96
+ # TODO: replace with a super call. This is useful for debugging for now.
97
+ raise "#{element} NOT FOUND WITH ARGS #{args}!!!"
98
+ end
99
+ end
100
+ # rubocop:enable Metrics/MethodLength
101
+
102
+ def respond_to_missing?(*args)
103
+ # Is this right at all???
104
+ case args[0].to_s
105
+ when /button/, /checkbox/, /element/, /link/, /text/,
106
+ 'driver', 'url', 'children', 'loaded?'
107
+ true
108
+ when 'ok_link'
109
+ raise 'OK LINK WAY DOWN HERE IN BASE PAGE!!!'
110
+ else
111
+ # I think it's good to raise but change the message.
112
+ raise 'TODO: BETTER ERROR MESSAGE, PLEASE. I AM SHOUTING!!!\n' \
113
+ 'Drew, you hit this most often when checking current page ' \
114
+ "rather than current page class:\n\n #{args}"
115
+ # I think I want to raise instead of returningn false.
116
+ end
117
+ end
118
+ end
119
+ end
@@ -1,3 +1,3 @@
1
1
  module RUTL
2
- VERSION = '0.3.0'.freeze
2
+ VERSION = '0.4.0'.freeze
3
3
  end
@@ -4,7 +4,7 @@
4
4
  module Utilities
5
5
  require 'timeout'
6
6
 
7
- POLL_SLEEP_TIME = 0.1
7
+ POLL_SLEEP_TIME = 0.01
8
8
  DEFAULT_TIMEOUT = 5
9
9
 
10
10
  # The lambda passed to await should return false if thing not found
@@ -33,13 +33,9 @@ module Utilities
33
33
  end
34
34
 
35
35
  def page?(checkme)
36
- checkme.ancestors.include?(BasePage)
36
+ checkme.ancestors.include?(RUTL::Page)
37
37
  rescue NoMethodError
38
38
  # This isn't a even a class. It's no page!
39
39
  false
40
40
  end
41
-
42
- def raise_if_not_page(page)
43
- raise "NOT A PAGE: #{page}. Ancestors: #{page.ancestors}" unless page?(page)
44
- end
45
41
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rutl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Drew Cooper
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-06-07 00:00:00.000000000 Z
11
+ date: 2018-06-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: selenium-webdriver
@@ -187,26 +187,17 @@ files:
187
187
  - lib/rspec/default_rspec_to_browser.rb
188
188
  - lib/rspec/rutl_matchers.rb
189
189
  - lib/rutl.rb
190
- - lib/rutl/base_page.rb
191
190
  - lib/rutl/browser.rb
192
- - lib/rutl/driver/null_driver.rb
193
- - lib/rutl/driver/null_driver_page_element.rb
191
+ - lib/rutl/camera.rb
194
192
  - lib/rutl/interface/base_interface.rb
195
193
  - lib/rutl/interface/chrome_interface.rb
196
- - lib/rutl/interface/elements.rb
197
- - lib/rutl/interface/elements/base_element.rb
198
- - lib/rutl/interface/elements/button.rb
199
- - lib/rutl/interface/elements/checkbox.rb
200
- - lib/rutl/interface/elements/click_to_change_state_mixin.rb
201
- - lib/rutl/interface/elements/element_context.rb
202
- - lib/rutl/interface/elements/link.rb
203
- - lib/rutl/interface/elements/string_reader_writer_mixin.rb
204
- - lib/rutl/interface/elements/text.rb
205
194
  - lib/rutl/interface/firefox_interface.rb
206
195
  - lib/rutl/interface/null_interface.rb
207
- - lib/rutl/screencam.rb
208
- - lib/rutl/utilities.rb
196
+ - lib/rutl/null_driver/null_driver.rb
197
+ - lib/rutl/null_driver/null_element.rb
198
+ - lib/rutl/page.rb
209
199
  - lib/rutl/version.rb
200
+ - lib/utilities.rb
210
201
  - rutl.gemspec
211
202
  homepage: https://github.com/drewcoo/rutl
212
203
  licenses: