add header support

This commit is contained in:
shogo-ohta 2011-06-08 18:36:45 +09:00 committed by os0x
parent ec3a827060
commit ee1388e329
14 changed files with 162 additions and 4 deletions

View File

@ -36,6 +36,10 @@ class Capybara::Driver::Webkit
source
end
def header(key, value)
browser.header(key, value)
end
def execute_script(script)
browser.execute_script script
end

View File

@ -14,6 +14,10 @@ class Capybara::Driver::Webkit
command "Visit", url
end
def header(key, value)
command("Header", key, value)
end
def find(query)
command("Find", query).split(",")
end

View File

@ -79,6 +79,61 @@ describe Capybara::Session do
subject.click_button('ボタン')
end
end
context "custom header" do
before(:all) do
@app = lambda do |env|
body = <<-HTML
<html><body>
<pre>#{env['HTTP_USER_AGENT']}</pre>
<pre>#{env['HTTP_X_CAPYBARA_WEBKIT_HEADER']}</pre>
<pre>#{env['HTTP_ACCEPT']}</pre>
<a href="/">/</a>
</body></html>
HTML
[200,
{ 'Content-Type' => 'text/html', 'Content-Length' => body.length.to_s },
[body]]
end
end
it "can set user_agent" do
subject.driver.header('user-agent', 'capybara-webkit/custom-user-agent')
subject.visit('/')
subject.should have_content('capybara-webkit/custom-user-agent')
subject.should be_true subject.driver.evaluate_script('navigator.userAgent').eql?('capybara-webkit/custom-user-agent')
end
it "reset default user_agent" do
subject.visit('/')
subject.should have_content('Mozilla/5.0')
subject.should be_true subject.driver.evaluate_script('navigator.userAgent').start_with?('Mozilla/5.0')
end
it "keep user_agent in next page" do
subject.driver.header('user-agent', 'capybara-webkit/custom-user-agent')
subject.visit('/')
subject.click_link('/')
subject.should have_content('capybara-webkit/custom-user-agent')
subject.should be_true subject.evaluate_script('navigator.userAgent').eql?('capybara-webkit/custom-user-agent')
end
it "can set custom header" do
subject.driver.header('x-capybara-webkit-header', 'x-capybara-webkit-spec')
subject.visit('/')
subject.should have_content('x-capybara-webkit-spec')
end
it "does not keep custom header" do
subject.visit('/')
subject.should_not have_content('x-capybara-webkit-spec')
end
it "can set Accept" do
subject.driver.header('accept', 'application/xhtml+xml')
subject.visit('/')
subject.should have_content('application/xhtml+xml')
end
end
end
describe Capybara::Session, "with TestApp" do

View File

@ -10,6 +10,7 @@
#include "Evaluate.h"
#include "Execute.h"
#include "FrameFocus.h"
#include "Header.h"
#include <QTcpSocket>
#include <iostream>

18
src/Header.cpp Normal file
View File

@ -0,0 +1,18 @@
#include "Header.h"
#include "WebPage.h"
#include "NetworkAccessManager.h"
Header::Header(WebPage *page, QObject *parent) : Command(page, parent) {
}
void Header::start(QStringList &arguments) {
QString key = arguments[0];
QString value = arguments[1];
NetworkAccessManager* nam = qobject_cast<NetworkAccessManager*>(page()->networkAccessManager());
if (key.toLower().replace("-", "_") == "user_agent") {
page()->setUserAgent(value);
} else {
nam->addHeader(key, value);
}
emit finished(new Response(true));
}

11
src/Header.h Normal file
View File

@ -0,0 +1,11 @@
#include "Command.h"
class WebPage;
class Header : public Command {
Q_OBJECT
public:
Header(WebPage *page, QObject *parent = 0);
virtual void start(QStringList &arguments);
};

View File

@ -0,0 +1,22 @@
#include "NetworkAccessManager.h"
#include "WebPage.h"
#include <iostream>
NetworkAccessManager::NetworkAccessManager(QObject *parent):QNetworkAccessManager(parent) {
}
QNetworkReply* NetworkAccessManager::createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice * outgoingData = 0) {
QNetworkRequest new_req(req);
QHashIterator<QString, QString> item(m_headers);
while (item.hasNext()) {
item.next();
new_req.setRawHeader(item.key().toAscii(), item.value().toAscii());
}
return QNetworkAccessManager::createRequest(op, new_req, outgoingData);
};
void NetworkAccessManager::addHeader(QString key, QString value) {
m_headers.insert(key, value);
};

View File

@ -0,0 +1,18 @@
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkReply>
class NetworkAccessManager : public QNetworkAccessManager {
Q_OBJECT
public:
NetworkAccessManager(QObject *parent = 0);
void addHeader(QString key, QString value);
protected:
QNetworkReply* createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice * outgoingData);
private:
QHash<QString, QString> m_headers;
};

View File

@ -1,5 +1,6 @@
#include "Reset.h"
#include "WebPage.h"
#include "NetworkAccessManager.h"
Reset::Reset(WebPage *page, QObject *parent) : Command(page, parent) {
}
@ -10,6 +11,8 @@ void Reset::start(QStringList &arguments) {
page()->triggerAction(QWebPage::Stop);
page()->currentFrame()->setHtml("<html><body></body></html>");
page()->networkAccessManager()->setCookieJar(new QNetworkCookieJar());
page()->setNetworkAccessManager(new NetworkAccessManager());
page()->setUserAgent(NULL);
emit finished(new Response(true));
}

View File

@ -8,11 +8,13 @@ Visit::Visit(WebPage *page, QObject *parent) : Command(page, parent) {
void Visit::start(QStringList &arguments) {
QUrl requestedUrl = QUrl(arguments[0]);
page()->currentFrame()->setUrl(QUrl(requestedUrl));
QNetworkRequest req;
req.setUrl(requestedUrl);
if(requestedUrl.hasFragment()) {
// workaround for https://bugs.webkit.org/show_bug.cgi?id=32723
page()->currentFrame()->setUrl(QUrl(requestedUrl));
req.setUrl(QUrl(requestedUrl));
}
page()->currentFrame()->load(req);
}
void Visit::loadFinished(bool success) {

View File

@ -1,5 +1,6 @@
#include "WebPage.h"
#include "JavascriptInvocation.h"
#include "NetworkAccessManager.h"
#include <QResource>
#include <iostream>
@ -15,12 +16,27 @@ WebPage::WebPage(QObject *parent) : QWebPage(parent) {
m_capybaraJavascript = javascriptString;
}
m_loading = false;
this->setNetworkAccessManager(new NetworkAccessManager());
connect(this, SIGNAL(loadStarted()), this, SLOT(loadStarted()));
connect(this, SIGNAL(loadFinished(bool)), this, SLOT(loadFinished(bool)));
connect(this, SIGNAL(frameCreated(QWebFrame *)),
this, SLOT(frameCreated(QWebFrame *)));
}
QString WebPage::userAgentForUrl(const QUrl &url ) const {
if (!m_user_agent.isEmpty()) {
return m_user_agent;
} else {
return QWebPage::userAgentForUrl(url);
}
}
void WebPage::setUserAgent(QString ua) {
m_user_agent = ua;
}
void WebPage::frameCreated(QWebFrame * frame) {
connect(frame, SIGNAL(javaScriptWindowObjectCleared()),
this, SLOT(injectJavascriptHelpers()));

View File

@ -8,6 +8,8 @@ class WebPage : public QWebPage {
QVariant invokeCapybaraFunction(const char *name, QStringList &arguments);
QVariant invokeCapybaraFunction(QString &name, QStringList &arguments);
QString failureString();
QString userAgentForUrl(const QUrl &url ) const;
void setUserAgent(QString ua);
public slots:
bool shouldInterruptJavaScript();
@ -25,6 +27,7 @@ class WebPage : public QWebPage {
private:
QString m_capybaraJavascript;
QString m_user_agent;
bool m_loading;
};

View File

@ -12,3 +12,4 @@ CHECK_COMMAND(Source)
CHECK_COMMAND(Evaluate)
CHECK_COMMAND(Execute)
CHECK_COMMAND(FrameFocus)
CHECK_COMMAND(Header)

View File

@ -1,8 +1,8 @@
TEMPLATE = app
TARGET = webkit_server
DESTDIR = .
HEADERS = WebPage.h Server.h Connection.h Command.h Visit.h Find.h Reset.h Node.h JavascriptInvocation.h Url.h Source.h Evaluate.h Execute.h FrameFocus.h Response.h
SOURCES = main.cpp WebPage.cpp Server.cpp Connection.cpp Command.cpp Visit.cpp Find.cpp Reset.cpp Node.cpp JavascriptInvocation.cpp Url.cpp Source.cpp Evaluate.cpp Execute.cpp FrameFocus.cpp Response.cpp
HEADERS = WebPage.h Server.h Connection.h Command.h Visit.h Find.h Reset.h Node.h JavascriptInvocation.h Url.h Source.h Evaluate.h Execute.h FrameFocus.h Response.h NetworkAccessManager.h Header.h
SOURCES = main.cpp WebPage.cpp Server.cpp Connection.cpp Command.cpp Visit.cpp Find.cpp Reset.cpp Node.cpp JavascriptInvocation.cpp Url.cpp Source.cpp Evaluate.cpp Execute.cpp FrameFocus.cpp Response.cpp NetworkAccessManager.cpp Header.cpp
RESOURCES = webkit_server.qrc
QT += network webkit
CONFIG += console