Finding nodes via XPath

This commit is contained in:
Jonas Nicklas 2009-11-05 00:34:11 +01:00
parent c4ee7eaa69
commit a138207e94
5 changed files with 89 additions and 6 deletions

View File

@ -3,7 +3,20 @@ require 'rack'
require 'net/http' require 'net/http'
class Webcat::Driver::Culerity class Webcat::Driver::Culerity
Response = Struct.new(:body) class Node < Struct.new(:node)
def text
node.text
end
def attribute(name)
value = if name.to_sym == :class
node.class_name
else
node.send(name.to_sym)
end
return value if value and not value.empty?
end
end
attr_reader :app, :rack_server attr_reader :app, :rack_server
@ -30,6 +43,10 @@ class Webcat::Driver::Culerity
def body def body
browser.html browser.html
end end
def find(selector)
browser.elements_by_xpath(selector).map { |node| Node.new(node) }
end
private private

View File

@ -1,6 +1,18 @@
require 'rack/test' require 'rack/test'
require 'nokogiri'
class Webcat::Driver::RackTest class Webcat::Driver::RackTest
class Node < Struct.new(:node)
def text
node.text
end
def attribute(name)
value = node.attributes[name.to_s]
return value.to_s if value
end
end
include ::Rack::Test::Methods include ::Rack::Test::Methods
attr_reader :app attr_reader :app
@ -18,4 +30,14 @@ class Webcat::Driver::RackTest
def body def body
response.body response.body
end end
def find(selector)
html.xpath(selector).map { |node| Node.new(node) }
end
private
def html
Nokogiri::HTML(body)
end
end end

View File

@ -1,7 +1,7 @@
require File.expand_path('spec_helper', File.dirname(__FILE__)) require File.expand_path('spec_helper', File.dirname(__FILE__))
shared_examples_for 'driver' do shared_examples_for 'driver' do
describe '#visit' do describe '#visit' do
it "should move to another page" do it "should move to another page" do
@driver.visit('/') @driver.visit('/')
@ -10,17 +10,42 @@ shared_examples_for 'driver' do
@driver.body.should == 'Another World' @driver.body.should == 'Another World'
end end
end end
describe '#body' do describe '#body' do
it "should return text reponses" do it "should return text reponses" do
@driver.visit('/') @driver.visit('/')
@driver.body.should == 'Hello world!' @driver.body.should == 'Hello world!'
end end
it "should return the full response html" do it "should return the full response html" do
@driver.visit('/with_simple_html') @driver.visit('/with_simple_html')
@driver.body.should == '<h1>Bar</h1>' @driver.body.should == '<h1>Bar</h1>'
end end
end end
end describe '#find' do
context "with xpath selector" do
before do
@driver.visit('/with_html')
end
it "should find the correct number of elements" do
@driver.find('//a').size.should == 2
end
it "should extract node texts" do
@driver.find('//a')[0].text.should == 'labore'
@driver.find('//a')[1].text.should == 'ullamco'
end
it "should extract node attributes" do
@driver.find('//a')[0].attribute(:href).should == '/with_simple_html'
@driver.find('//a')[0].attribute(:class).should == 'simple'
@driver.find('//a')[1].attribute(:href).should == '/foo'
@driver.find('//a')[1].attribute(:id).should == 'foo'
@driver.find('//a')[1].attribute(:rel).should be_nil
end
end
end
end

View File

@ -8,6 +8,10 @@ class TestApp < Sinatra::Base
get '/foo' do get '/foo' do
'Another World' 'Another World'
end end
get '/with_html' do
erb :with_html
end
get '/with_simple_html' do get '/with_simple_html' do
erb :with_simple_html erb :with_simple_html

15
spec/views/with_html.erb Normal file
View File

@ -0,0 +1,15 @@
<h1>This is a test</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut <a href="/with_simple_html" class="simple">labore</a>
et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation <a href="/foo" id="foo">ullamco</a> laboris nisi
ut aliquip ex ea commodo consequat.
</p>
<p>
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>