rutl 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/rutl/element.rb +6 -0
- data/lib/rutl/element/button.rb +14 -0
- data/lib/rutl/element/checkbox.rb +12 -0
- data/lib/rutl/element/click_to_change_state_mixin.rb +24 -0
- data/lib/rutl/element/element.rb +51 -0
- data/lib/rutl/element/element_context.rb +38 -0
- data/lib/rutl/element/link.rb +15 -0
- data/lib/rutl/element/string_reader_writer_mixin.rb +77 -0
- data/lib/rutl/element/text.rb +14 -0
- data/lib/rutl/version.rb +1 -1
- metadata +10 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1f2590f32dfe005e1508e0e88f3faa3a840173da6bf67313f0e951642c13e611
|
4
|
+
data.tar.gz: 500cbd32f70149497bd3a1decdccb21678f2e516d3b97e96aeaa4a2d5abfc72b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f312505641be60572b85da6fbe890a49be75af82f5c61c5f484b39e11596706f3c3b04c699a3759da8774227d1f86c1c18502ed8d765fe389a04c9c7c7a88505
|
7
|
+
data.tar.gz: f0dd36b84da17dc6a4db7d61ae973f024a8f940ef408a27be3d79422e5a11a7989b178ce549bc6a3e4052fc5fd1971c93522c0ebb6479776fa75b8e8644ad19e
|
data/lib/rutl/element.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rutl/element/element'
|
2
|
+
require 'rutl/element/click_to_change_state_mixin'
|
3
|
+
|
4
|
+
module RUTL
|
5
|
+
module Element
|
6
|
+
#
|
7
|
+
# It's a button!
|
8
|
+
#
|
9
|
+
class Button < Element
|
10
|
+
include ClickToChangeStateMixin
|
11
|
+
# def get, text - return button text; useful for text-changing buttons
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module RUTL
|
2
|
+
module Element
|
3
|
+
#
|
4
|
+
# Mix this in for things that change state when clicked.
|
5
|
+
# The only things that wouldn't change state when clicked either
|
6
|
+
# shouldn't be clicked or are just annoying.
|
7
|
+
#
|
8
|
+
module ClickToChangeStateMixin
|
9
|
+
# click does:
|
10
|
+
# * Screenshot before clicking. Is this really necessary?
|
11
|
+
# * Click.
|
12
|
+
# * Waits for transition to post-click state. (Polls until one reached.)
|
13
|
+
# * Screenshot again after the transition. This one is definitely needed.
|
14
|
+
# * Returns the state we transitioned to.
|
15
|
+
def click
|
16
|
+
@context.interface.camera.screenshot
|
17
|
+
this_css.click
|
18
|
+
result = @context.interface.wait_for_transition(@context.destinations)
|
19
|
+
@context.interface.camera.screenshot
|
20
|
+
result
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module RUTL
|
2
|
+
module Element
|
3
|
+
#
|
4
|
+
# Page element base class.
|
5
|
+
#
|
6
|
+
class Element
|
7
|
+
attr_accessor :context
|
8
|
+
|
9
|
+
def initialize(element_context)
|
10
|
+
raise element_context.to_s unless element_context.is_a? ElementContext
|
11
|
+
@context = element_context
|
12
|
+
# Not sure why, but I'm seeing Chrome fail becase the context interface
|
13
|
+
# passed in isn't the same as the browser's interface.
|
14
|
+
# This only happens with click test cases, before the click, and
|
15
|
+
# only if that case isn't run first.
|
16
|
+
# The context we're passed is also an instance from as ChromeInterface,
|
17
|
+
# but a different instance.
|
18
|
+
#
|
19
|
+
# Here's the kludge workaround line:
|
20
|
+
@context.interface = $browser.interface
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns the element at this css selector.
|
24
|
+
def this_css
|
25
|
+
@context.find_element(:css)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Returns boolean, of course.
|
29
|
+
# Unlike the underlying Selenium library, I have .exists? because I may
|
30
|
+
# have a valid Element object for something that doesn't exist. Anymore.
|
31
|
+
# Or yet.
|
32
|
+
def exists?
|
33
|
+
this_css
|
34
|
+
rescue Selenium::WebDriver::Error::NoSuchElementError
|
35
|
+
false
|
36
|
+
end
|
37
|
+
|
38
|
+
def method_missing(method, *args, &block)
|
39
|
+
if args.empty?
|
40
|
+
this_css.send(method)
|
41
|
+
else
|
42
|
+
this_css.send(method, *args, &block)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def respond_to_missing?(*args)
|
47
|
+
this_css.respond_to?(*args)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module RUTL
|
2
|
+
module Element
|
3
|
+
#
|
4
|
+
# The context passed around to all elements.
|
5
|
+
# What they need to know outside of themselves to function.
|
6
|
+
#
|
7
|
+
class ElementContext
|
8
|
+
# Nil. Or an Array. One would hope an Array of states. But I'm not checking.
|
9
|
+
attr_accessor :destinations
|
10
|
+
# Nil. Or a RUTL::BaseInterface.
|
11
|
+
attr_accessor :interface
|
12
|
+
# An Arrray, maybe empty and maybe an array of selectors.
|
13
|
+
# TODO: This should be a hash.
|
14
|
+
attr_accessor :selectors
|
15
|
+
|
16
|
+
def initialize(destinations: nil, interface: nil, selectors: [])
|
17
|
+
unless destinations.nil? || destinations.class == Array
|
18
|
+
# Should check each destination to make sure it's a
|
19
|
+
# Page or a _____, too.
|
20
|
+
raise 'destination must be an Array of destinations or nil.'
|
21
|
+
end
|
22
|
+
@destinations = destinations || []
|
23
|
+
unless interface.nil? || interface.is_a?(RUTL::BaseInterface)
|
24
|
+
raise "#{interface.class}: #{interface} must be a *Interface class."
|
25
|
+
end
|
26
|
+
@interface = interface
|
27
|
+
@selectors = selectors
|
28
|
+
end
|
29
|
+
|
30
|
+
def find_element(type)
|
31
|
+
# @interface.driver.find_element(type, @selectors[type])
|
32
|
+
# Should be this, but apparently @interface.driver is being overwritten
|
33
|
+
# (or not written to) and it doesn't work. Using $browser does. :-(
|
34
|
+
$browser.interface.driver.find_element(type, @selectors[type])
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rutl/element/element'
|
2
|
+
require 'rutl/element/click_to_change_state_mixin'
|
3
|
+
|
4
|
+
module RUTL
|
5
|
+
module Element
|
6
|
+
#
|
7
|
+
# Link, of course.
|
8
|
+
#
|
9
|
+
class Link < Element
|
10
|
+
include ClickToChangeStateMixin
|
11
|
+
# text, url - get what they say
|
12
|
+
# should there be a 'get' - what would it get?
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module RUTL
|
2
|
+
module Element
|
3
|
+
#
|
4
|
+
# Implement String stuff in a mixin.
|
5
|
+
# TODO: Not finished yet. Must be able to
|
6
|
+
#
|
7
|
+
module StringReaderWriterMixin
|
8
|
+
# Override BaseElement's normal initialize method.
|
9
|
+
def initialize(element_context, input_value = nil)
|
10
|
+
raise element_context.to_s unless element_context.is_a? ElementContext
|
11
|
+
@context = element_context
|
12
|
+
set input_value unless input_value.nil?
|
13
|
+
end
|
14
|
+
|
15
|
+
# I could cut set() and only foo_text= if I change this.
|
16
|
+
# The problem I'm running into is not having the driver in
|
17
|
+
# base element to do this_css calls. So I have to change the way
|
18
|
+
# drivers are passed into everything or initially have them everywhere,
|
19
|
+
# which means rewriting chosen drivers or changing page load.
|
20
|
+
# Ick.
|
21
|
+
def set(string)
|
22
|
+
clear
|
23
|
+
this_css.send_keys(string)
|
24
|
+
end
|
25
|
+
alias text= set
|
26
|
+
alias value= set
|
27
|
+
|
28
|
+
# Return the String held by this element.
|
29
|
+
def get
|
30
|
+
this_css.attribute(:value)
|
31
|
+
end
|
32
|
+
alias text get
|
33
|
+
alias value get
|
34
|
+
alias to_s get
|
35
|
+
|
36
|
+
# Talk to the page and set the element's string to ''.
|
37
|
+
def clear
|
38
|
+
this_css.clear
|
39
|
+
get
|
40
|
+
end
|
41
|
+
|
42
|
+
# String value equals.
|
43
|
+
def eql?(other)
|
44
|
+
other == get
|
45
|
+
end
|
46
|
+
alias == eql?
|
47
|
+
|
48
|
+
# Sends these keystrokes without clearing the field.
|
49
|
+
# Returns the whole string in the field, including this input.
|
50
|
+
def send_keys(string)
|
51
|
+
this_css.send_keys(string)
|
52
|
+
get
|
53
|
+
end
|
54
|
+
|
55
|
+
def method_missing(method, *args, &block)
|
56
|
+
# RuboCop complains unless I fall back to super here
|
57
|
+
# even though that's pretty meaningless. Oh, well, it's harmless.
|
58
|
+
super unless get.respond_to?(method)
|
59
|
+
if args.empty?
|
60
|
+
get.send(method)
|
61
|
+
else
|
62
|
+
get.send(method, *args, &block)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def respond_to_missing?(method, flag)
|
67
|
+
get.respond_to?(method, flag)
|
68
|
+
end
|
69
|
+
|
70
|
+
#
|
71
|
+
# TODO: Fall through to String methods? I already fall through to
|
72
|
+
# Selenium's Element methods in the Element class, so . . .
|
73
|
+
# it's complicated.
|
74
|
+
#
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rutl/element/element'
|
2
|
+
require 'rutl/element/string_reader_writer_mixin.rb'
|
3
|
+
|
4
|
+
module RUTL
|
5
|
+
module Element
|
6
|
+
#
|
7
|
+
# I'm using the text element for all text-like things. Passowrds, too.
|
8
|
+
# TODO: Also have a reader only class with StringReaderMixin for labels?
|
9
|
+
#
|
10
|
+
class Text < Element
|
11
|
+
include StringReaderWriterMixin
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/rutl/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rutl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Drew Cooper
|
@@ -189,6 +189,15 @@ files:
|
|
189
189
|
- lib/rutl.rb
|
190
190
|
- lib/rutl/browser.rb
|
191
191
|
- lib/rutl/camera.rb
|
192
|
+
- lib/rutl/element.rb
|
193
|
+
- lib/rutl/element/button.rb
|
194
|
+
- lib/rutl/element/checkbox.rb
|
195
|
+
- lib/rutl/element/click_to_change_state_mixin.rb
|
196
|
+
- lib/rutl/element/element.rb
|
197
|
+
- lib/rutl/element/element_context.rb
|
198
|
+
- lib/rutl/element/link.rb
|
199
|
+
- lib/rutl/element/string_reader_writer_mixin.rb
|
200
|
+
- lib/rutl/element/text.rb
|
192
201
|
- lib/rutl/interface/base_interface.rb
|
193
202
|
- lib/rutl/interface/chrome_interface.rb
|
194
203
|
- lib/rutl/interface/firefox_interface.rb
|