rutl 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: