Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 9 additions & 10 deletions lib/ae_page_objects.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,22 @@ module Dsl
autoload :FormFor, 'ae_page_objects/core/dsl/form_for'
end

module Methods
autoload :Node, 'ae_page_objects/methods/node'
module Concerns
autoload :LoadEnsuring, 'ae_page_objects/concerns/load_ensuring'
autoload :Staleable, 'ae_page_objects/concerns/staleable'
autoload :Visitable, 'ae_page_objects/concerns/visitable'
end

autoload :Node, 'ae_page_objects/node'
autoload :Document, 'ae_page_objects/document'
autoload :Element, 'ae_page_objects/element'
autoload :ElementProxy, 'ae_page_objects/element_proxy'
autoload :HasOne, 'ae_page_objects/has_one'
autoload :Collection, 'ae_page_objects/collection'
autoload :Form, 'ae_page_objects/form'
autoload :Select, 'ae_page_objects/select'
autoload :Checkbox, 'ae_page_objects/checkbox'

autoload :LoadEnsuring, 'ae_page_objects/load_ensuring'
autoload :Staleable, 'ae_page_objects/staleable'
autoload :Visitable, 'ae_page_objects/visitable'
autoload :HasOne, 'ae_page_objects/elements/has_one'
autoload :Collection, 'ae_page_objects/elements/collection'
autoload :Form, 'ae_page_objects/elements/form'
autoload :Select, 'ae_page_objects/elements/select'
autoload :Checkbox, 'ae_page_objects/elements/checkbox'
end

ActiveSupport::Dependencies.extend AePageObjects::DependenciesHook
Expand Down
30 changes: 30 additions & 0 deletions lib/ae_page_objects/concerns/load_ensuring.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
module AePageObjects
class LoadingFailed < StandardError
end

module Concerns
module LoadEnsuring
extend ActiveSupport::Concern

def initialize(*args)
super
ensure_loaded!
end

private

def loaded_locator
end

def ensure_loaded!
if locator = loaded_locator
find(*eval_locator(locator))
end

self
rescue Capybara::ElementNotFound => e
raise LoadingFailed, e.message
end
end
end
end
29 changes: 29 additions & 0 deletions lib/ae_page_objects/concerns/staleable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
module AePageObjects
class StalePageObject < StandardError
end

module Concerns
module Staleable
extend ActiveSupport::Concern

def stale?
@stale
end

def node
if stale?
raise StalePageObject, "Can't access stale page object '#{self}'"
end

super
end

private

def stale!
@stale = true
end

end
end
end
61 changes: 61 additions & 0 deletions lib/ae_page_objects/concerns/visitable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
module AePageObjects
class PathNotResolvable < StandardError
end

module Concerns
module Visitable
extend ActiveSupport::Concern

private

def ensure_loaded!
unless self.class.can_load_from_current_url?
raise LoadingFailed, "#{self.class.name} cannot be loaded with url '#{current_url_without_params}'"
end

super
end

module VisitMethod
def visit(*args)
raise ArgumentError, "Cannot pass block to visit()" if block_given?

full_path = application.generate_path(paths.first, *args)
raise PathNotResolvable, "#{self.name} not visitable via #{paths.first}(#{args.inspect})" unless full_path

Capybara.current_session.visit(full_path)
new
end
end

module ClassMethods

def can_load_from_current_url?
return true if paths.empty?

Capybara.current_session.wait_until do
url = current_url_without_params

paths.any? do |path|
application.path_recognizes_url?(path, url)
end
end
end

private

def paths
@paths ||= []
end

def path(path_method)
raise ArgumentError, "path must be a symbol or string" if ! path_method.is_a?(Symbol) && ! path_method.is_a?(String)

paths << path_method

extend VisitMethod
end
end
end
end
end
2 changes: 1 addition & 1 deletion lib/ae_page_objects/document.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module AePageObjects
class Document < Node
include Visitable
include Concerns::Visitable

def document
self
Expand Down
File renamed without changes.
28 changes: 0 additions & 28 deletions lib/ae_page_objects/load_ensuring.rb

This file was deleted.

69 changes: 0 additions & 69 deletions lib/ae_page_objects/methods/node.rb

This file was deleted.

72 changes: 69 additions & 3 deletions lib/ae_page_objects/node.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,73 @@
module AePageObjects
class Node
include Methods::Node
include LoadEnsuring
include Staleable
module Methods
extend ActiveSupport::Concern

include Dsl::Element
include Dsl::NestedElement
include Dsl::Collection
include Dsl::FormFor

def initialize(capybara_node = Capybara.current_session)
@node = capybara_node
end

def node
@node
end

def document
raise "Must implement!"
end

delegate :current_url, :to => 'self.class'
delegate :current_url_without_params, :to => 'self.class'

delegate :find, :to => :node
delegate :all, :to => :node
delegate :value, :to => :node
delegate :set, :to => :node
delegate :text, :to => :node
delegate :visible?, :to => :node

private

def eval_locator(locator)
return unless locator

if locator.respond_to?(:call)
locator = instance_eval(&locator)
end

locator.is_a?(Array) ? locator : [locator.to_s]
end

module ClassMethods

def current_url
Capybara.current_session.current_url.sub(/^https?:\/\/[^\/]*/, '')
end

def current_url_without_params
current_url.sub(/\?.*/, '')
end

def new_subclass(&block)
klass = Class.new(self)
klass.class_eval(&block) if block
klass
end

def new(*args)
super(*args).tap do |me|
yield me if block_given?
end
end
end
end

include Methods
include Concerns::LoadEnsuring
include Concerns::Staleable
end
end
27 changes: 0 additions & 27 deletions lib/ae_page_objects/staleable.rb

This file was deleted.

Loading