Support nested scoping

This commit is contained in:
Bryan Helmkamp 2008-11-07 01:09:00 -05:00
parent 7b3e6fa118
commit 13c4e42389
3 changed files with 54 additions and 18 deletions

View File

@ -9,11 +9,23 @@ module Webrat
include Flunk include Flunk
include Locators include Locators
def initialize(session, response, response_body, selector = nil) def self.from_page(session, response, response_body)
@session = session new(session) do
@response = response @response = response
@response_body = response_body @response_body = response_body
@selector = selector end
end
def self.from_scope(session, scope, selector)
new(session) do
@scope = scope
@selector = selector
end
end
def initialize(session, &block)
@session = session
instance_eval(&block) if block_given?
end end
# Verifies an input field or textarea exists on the current page, and stores a value for # Verifies an input field or textarea exists on the current page, and stores a value for
@ -143,18 +155,8 @@ module Webrat
def dom # :nodoc: def dom # :nodoc:
return @dom if @dom return @dom if @dom
if @response.respond_to?(:dom)
page_dom = @response.dom
else
page_dom = Nokogiri::HTML(@response_body)
@response.meta_class.send(:define_method, :dom) do
page_dom
end
end
if @selector if @selector
@dom = Nokogiri::HTML(page_dom.search(@selector).first.to_html) @dom = scoped_dom
else else
@dom = page_dom @dom = page_dom
end end
@ -164,6 +166,22 @@ module Webrat
protected protected
def page_dom
return @response.dom if @response.respond_to?(:dom)
dom = Nokogiri::HTML(@response_body)
@response.meta_class.send(:define_method, :dom) do
dom
end
return dom
end
def scoped_dom
Nokogiri::HTML(@scope.dom.search(@selector).first.to_html)
end
def locate_field(field_locator, *field_types) def locate_field(field_locator, *field_types)
if field_locator.is_a?(Field) if field_locator.is_a?(Field)
field_locator field_locator

View File

@ -133,7 +133,7 @@ module Webrat
alias_method :clicks_link_within, :click_link_within alias_method :clicks_link_within, :click_link_within
def within(selector) def within(selector)
scopes.push(Scope.new(self, response, response_body, selector)) scopes.push(Scope.from_scope(self, current_scope, selector))
ret = yield(current_scope) ret = yield(current_scope)
scopes.pop scopes.pop
return ret return ret
@ -169,7 +169,7 @@ module Webrat
end end
def page_scope def page_scope
@_page_scope ||= Scope.new(self, response, response_body) @_page_scope ||= Scope.from_page(self, response, response_body)
end end
def_delegators :current_scope, :fill_in, :fills_in def_delegators :current_scope, :fill_in, :fills_in

View File

@ -5,6 +5,24 @@ describe "within" do
@session = Webrat::TestSession.new @session = Webrat::TestSession.new
end end
it "should work when nested" do
@session.response_body = <<-EOS
<div>
<a href="/page1">Link</a>
</div>
<div id="container">
<div><a href="/page2">Link</a></div>
</div>
EOS
@session.should_receive(:get).with("/page2", {})
@session.within "#container" do
@session.within "div" do
@session.click_link "Link"
end
end
end
it "should click links within a scope" do it "should click links within a scope" do
@session.response_body = <<-EOS @session.response_body = <<-EOS
<a href="/page1">Link</a> <a href="/page1">Link</a>