Implement Driver#evaluateScript

This commit is contained in:
Joe Ferris 2011-02-26 13:02:43 -05:00
parent 22705199eb
commit 13426ba4c1
11 changed files with 182 additions and 5 deletions

View File

@ -22,8 +22,8 @@ task :generate_command do
Dir.glob("src/*.pro").each do |project_file_name|
project = IO.read(project_file_name)
project.gsub!(/(HEADERS = .*)/, "\\1 #{name}.h")
project.gsub!(/(SOURCES = .*)/, "\\1 #{name}.cpp")
project.gsub!(/^(HEADERS = .*)/, "\\1 #{name}.h")
project.gsub!(/^(SOURCES = .*)/, "\\1 #{name}.cpp")
File.open(project_file_name, "w") { |file| file.write(project) }
end

View File

@ -41,7 +41,7 @@ class Capybara::Driver::Webkit
end
def evaluate_script(script)
raise Capybara::NotSupportedByDriverError
browser.evaluate_script script
end
def response_headers

View File

@ -1,5 +1,6 @@
require 'socket'
require 'capybara/util/timeout'
require 'json'
class Capybara::Driver::Webkit
class Browser
@ -36,6 +37,12 @@ class Capybara::Driver::Webkit
read_response
end
def evaluate_script(script)
json = command('Evaluate', script)
puts "Got JSON: #{json}"
JSON.parse("[#{json}]").first
end
private
def start_server

View File

@ -65,5 +65,50 @@ describe Capybara::Driver::Webkit do
it "aliases body as source" do
subject.body.should == subject.source
end
it "evaluates Javascript and returns a string" do
result = subject.evaluate_script(%<document.getElementById('greeting').innerText>)
result.should == "hello"
end
it "evaluates Javascript and returns an array" do
result = subject.evaluate_script(%<["hello", "world"]>)
result.should == %w(hello world)
end
it "evaluates Javascript and returns an int" do
result = subject.evaluate_script(%<123>)
result.should == 123
end
it "evaluates Javascript and returns a float" do
result = subject.evaluate_script(%<1.5>)
result.should == 1.5
end
it "evaluates Javascript and returns null" do
result = subject.evaluate_script(%<(function () {})()>)
result.should == nil
end
it "evaluates Javascript and returns an object" do
result = subject.evaluate_script(%<({ 'one' : 1 })>)
result.should == { 'one' => 1 }
end
it "evaluates Javascript and returns true" do
result = subject.evaluate_script(%<true>)
result.should === true
end
it "evaluates Javascript and returns false" do
result = subject.evaluate_script(%<false>)
result.should === false
end
it "evaluates Javascript and returns an escaped string" do
result = subject.evaluate_script(%<'"'>)
result.should === "\""
end
end

View File

@ -6,8 +6,10 @@
#include "Node.h"
#include "Url.h"
#include "Source.h"
#include "Evaluate.h"
#include <QTcpSocket>
#include <iostream>
Connection::Connection(QTcpSocket *socket, WebPage *page, QObject *parent) :
QObject(parent) {
@ -38,6 +40,7 @@ void Connection::processLine(const char *line) {
} else {
m_command = createCommand(line);
if (m_command) {
std::cout << "Starting command: " << line << std::endl;
startCommand();
} else {
m_socket->write("bad command\n");
@ -74,6 +77,7 @@ void Connection::finishCommand(bool success, QString &response) {
m_command->deleteLater();
m_command = NULL;
m_arguments.clear();
std::cout << "Finished command" << std::endl;
if (success) {
m_socket->write("ok\n");
} else {

88
src/Evaluate.cpp Normal file
View File

@ -0,0 +1,88 @@
#include "Evaluate.h"
#include "WebPage.h"
#include <iostream>
Evaluate::Evaluate(WebPage *page, QObject *parent) : Command(page, parent) {
m_buffer = "";
}
void Evaluate::start(QStringList &arguments) {
Q_UNUSED(arguments);
QVariant result = page()->mainFrame()->evaluateJavaScript(arguments[0]);
addVariant(result);
emit finished(true, m_buffer);
}
void Evaluate::addVariant(QVariant &object) {
if (object.isValid()) {
std::cout << "Got type:" << object.typeName() << std::endl;
switch(object.type()) {
case QMetaType::QString:
{
QString string = object.toString();
addString(string);
}
break;
case QMetaType::QVariantList:
{
QVariantList list = object.toList();
addArray(list);
}
break;
case QMetaType::Double:
m_buffer.append(object.toString());
break;
case QMetaType::QVariantMap:
{
QVariantMap map = object.toMap();
addMap(map);
break;
}
case QMetaType::Bool:
{
m_buffer.append(object.toString());
break;
}
default:
m_buffer.append("null");
}
} else {
std::cout << "Got invalid result" << std::endl;
m_buffer.append("null");
}
}
void Evaluate::addString(QString &string) {
QString escapedString(string);
escapedString.replace("\"", "\\\"");
m_buffer.append("\"");
m_buffer.append(escapedString);
m_buffer.append("\"");
}
void Evaluate::addArray(QVariantList &list) {
m_buffer.append("[");
for (int i = 0; i < list.length(); i++) {
if (i > 0)
m_buffer.append(",");
addVariant(list[i]);
}
m_buffer.append("]");
}
void Evaluate::addMap(QVariantMap &map) {
m_buffer.append("{");
QMapIterator<QString, QVariant> iterator(map);
while (iterator.hasNext()) {
iterator.next();
QString key = iterator.key();
QVariant value = iterator.value();
addString(key);
m_buffer.append(":");
addVariant(value);
if (iterator.hasNext())
m_buffer.append(",");
}
m_buffer.append("}");
}

22
src/Evaluate.h Normal file
View File

@ -0,0 +1,22 @@
#include "Command.h"
#include <QVariantList>
class WebPage;
class Evaluate : public Command {
Q_OBJECT
public:
Evaluate(WebPage *page, QObject *parent = 0);
virtual void start(QStringList &arguments);
private:
void addVariant(QVariant &object);
void addString(QString &string);
void addArray(QVariantList &list);
void addMap(QVariantMap &map);
QString m_buffer;
};

View File

@ -1,6 +1,7 @@
#include "WebPage.h"
#include "JavascriptInvocation.h"
#include <QResource>
#include <iostream>
WebPage::WebPage(QObject *parent) : QWebPage(parent) {
connect(mainFrame(), SIGNAL(javaScriptWindowObjectCleared()),
@ -30,3 +31,9 @@ QVariant WebPage::invokeCapybaraFunction(QString &name, QStringList &arguments)
return invokeCapybaraFunction(name.toAscii().data(), arguments);
}
void WebPage::javaScriptConsoleMessage(const QString &message, int lineNumber, const QString &sourceID) {
if (!sourceID.isEmpty())
std::cout << qPrintable(sourceID) << ":" << lineNumber << " ";
std::cout << qPrintable(message) << std::endl;
}

View File

@ -12,6 +12,9 @@ class WebPage : public QWebPage {
bool shouldInterruptJavaScript();
void injectJavascriptHelpers();
protected:
virtual void javaScriptConsoleMessage(const QString &message, int lineNumber, const QString &sourceID);
private:
QString m_capybaraJavascript;
};

View File

@ -9,3 +9,4 @@ CHECK_COMMAND(Reset)
CHECK_COMMAND(Node)
CHECK_COMMAND(Url)
CHECK_COMMAND(Source)
CHECK_COMMAND(Evaluate)

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
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
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
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
RESOURCES = webkit_server.qrc
QT += network webkit
CONFIG += console