merge latest from master

This commit is contained in:
Will Ryan 2012-03-23 16:10:41 -04:00
commit 312156ea6f
69 changed files with 258 additions and 253 deletions

4
.gitignore vendored
View File

@ -1,5 +1,5 @@
*.swp
bin/webkit_server
bin/webkit_server*
*.swo
*~
*.o
@ -12,6 +12,8 @@ moc_*.cpp
.bundle
pkg
src/webkit_server
src/webkit_server.exe
.DS_Store
tmp
.rvmrc
src/debug

View File

@ -1,3 +1,9 @@
2012-03-09 Joe Ferris <jferris@thoughtbot.com>
* node.rb, driver_spec.rb: Allow interaction with invisible elements
2012-03-02 Joe Ferris <jferris@thoughtbot.com>
* browser.rb: Use Timeout from stdlib since Capybara.timeout is being removed
2012-03-02 Matthew Mongeau <halogenandtoast@gmail.com>
* capybara_webkit_builder.rb:
set LANG to en_US.UTF-8 to prevent string encoding issues during install

View File

@ -1,7 +1,7 @@
PATH
remote: .
specs:
capybara-webkit (0.10.1)
capybara-webkit (0.11.0)
capybara (>= 1.0.0, < 1.2)
json
@ -56,6 +56,7 @@ GEM
PLATFORMS
ruby
x86-mingw32
DEPENDENCIES
appraisal (~> 0.4.0)

View File

@ -1,4 +1,10 @@
New for 0.11.0:
* Allow interaction with invisible elements
* Use Timeout from stdlib since Capybara.timeout is being removed
New for 0.10.1:
* LANG environment variable is set to en_US.UTF-8 in order to avoid string encoding issues from qmake.
* pro, find_command, and CommandFactory are more structured.
* Changed wiki link and directing platform specific issues to the google group.

View File

@ -11,6 +11,11 @@ development toolkit. You'll need to download the Qt libraries to build and
install the gem. You can find instructions for downloading and installing QT on
the [capybara-webkit wiki](https://github.com/thoughtbot/capybara-webkit/wiki/Installing-Qt-and-compiling-capybara-webkit)
Windows Support
---------------
Currently 32bit Windows will compile Capybara-webkit. Support for Windows is provided by the open source community and Windows related issues should be posted to the [mailing list](http://groups.google.com/group/capybara-webkit)
Reporting Issues
----------------

View File

@ -147,11 +147,19 @@ class Capybara::Driver::Webkit
pipe
end
def kill_process(pid)
if RUBY_PLATFORM =~ /mingw32/
Process.kill(9, pid)
else
Process.kill("INT", pid)
end
end
def register_shutdown_hook
@owner_pid = Process.pid
at_exit do
if Process.pid == @owner_pid
Process.kill("INT", @pid)
kill_process(@pid)
end
end
end

View File

@ -1,9 +1,5 @@
class Capybara::Driver::Webkit
class Node < Capybara::Driver::Node
class ElementNotDisplayedError < StandardError
end
NBSP = "\xC2\xA0"
NBSP.force_encoding("UTF-8") if NBSP.respond_to?(:force_encoding)
@ -33,7 +29,6 @@ class Capybara::Driver::Webkit
end
def select_option
check_visibility(self)
invoke "selectOption"
end
@ -47,13 +42,10 @@ class Capybara::Driver::Webkit
end
def click
check_visibility(self)
invoke "click"
end
def drag_to(element)
check_visibility(self)
check_visibility(element)
invoke 'dragTo', element.native
end
@ -122,9 +114,5 @@ class Capybara::Driver::Webkit
def multiple_select?
self.tag_name == "select" && self["multiple"] == "multiple"
end
def check_visibility(element)
raise(ElementNotDisplayedError, "This element is not visible so it may not be interacted with") unless element.visible?
end
end
end

View File

@ -1,7 +1,7 @@
module Capybara
module Driver
class Webkit
VERSION = '0.10.1'.freeze
VERSION = '0.11.0'.freeze
end
end
end

View File

@ -1,9 +1,7 @@
module Capybara
module Webkit
module RspecMatchers
extend RSpec::Matchers::DSL
matcher :have_errors do |expected|
RSpec::Matchers.define :have_errors do |expected|
match do |actual|
actual = resolve(actual)
actual.error_messages.any?
@ -12,6 +10,7 @@ module Capybara
failure_message_for_should do |actual|
"Expected Javascript errors, but there were none."
end
failure_message_for_should_not do |actual|
actual = resolve(actual)
"Expected no Javascript errors, got:\n#{error_messages_for(actual)}"
@ -33,7 +32,6 @@ module Capybara
end
end
end
end
end
end

View File

@ -22,6 +22,8 @@ module CapybaraWebkitBuilder
"linux-g++"
when /freebsd/
"freebsd-g++"
when /mingw32/
"win32-g++"
else
"macx-g++"
end
@ -35,11 +37,20 @@ module CapybaraWebkitBuilder
system("LANG='en_US.UTF-8' #{make_bin} qmake")
end
def path_to_binary
case RUBY_PLATFORM
when /mingw32/
"src/debug/webkit_server.exe"
else
"src/webkit_server"
end
end
def build
system(make_bin) or return false
FileUtils.mkdir("bin") unless File.directory?("bin")
FileUtils.cp("src/webkit_server", "bin", :preserve => true)
FileUtils.cp(path_to_binary, "bin", :preserve => true)
end
def build_all

View File

@ -81,7 +81,8 @@ describe Capybara::Driver::Webkit::Browser do
browser_ignore_ssl_err.visit "https://#{@host}:#{@port}/"
end
end
describe "forking" do
describe "forking", :skip_on_windows => true do
it "only shuts down the server from the main process" do
browser.reset!
pid = fork {}

View File

@ -659,6 +659,7 @@ describe Capybara::Driver::Webkit do
element.addEventListener("keydown", recordEvent);
element.addEventListener("keypress", recordEvent);
element.addEventListener("keyup", recordEvent);
element.addEventListener("input", recordEvent);
element.addEventListener("change", recordEvent);
element.addEventListener("blur", recordEvent);
element.addEventListener("mousedown", recordEvent);
@ -678,7 +679,7 @@ describe Capybara::Driver::Webkit do
let(:keyevents) do
(%w{focus} +
newtext.length.times.collect { %w{keydown keypress keyup} } +
newtext.length.times.collect { %w{keydown keypress keyup input} } +
%w{change blur}).flatten
end
@ -713,13 +714,10 @@ describe Capybara::Driver::Webkit do
<div id="change">Change me</div>
<div id="mouseup">Push me</div>
<div id="mousedown">Release me</div>
<div id="invisible-mouseup" style="display:none;">You can't push me</div>
<div id="invisible-mousedown" style="display:none;">You can't release me</div>
<form action="/" method="GET">
<select id="change_select" name="change_select">
<option value="1" id="option-1" selected="selected">one</option>
<option value="2" id="option-2">two</option>
<option value="2" id="invisible-option" style="display:none;">three</option>
</select>
</form>
<script type="text/javascript">
@ -741,7 +739,6 @@ describe Capybara::Driver::Webkit do
});
</script>
<a href="/next">Next</a>
<a href="/next" id="hidden" style="display:none;">Not displayed</a>
</body></html>
HTML
[200,
@ -750,7 +747,7 @@ describe Capybara::Driver::Webkit do
end
end
it "clicks a visible element" do
it "clicks an element" do
subject.find("//a").first.click
subject.current_url =~ %r{/next$}
end
@ -782,39 +779,6 @@ describe Capybara::Driver::Webkit do
subject.find("//*[@class='triggered']").size.should == 1
end
context "raises error when" do
it "tries to click an invisible element" do
expect {
subject.find("//*[@id='hidden']").first.click
}.to raise_error(Capybara::Driver::Webkit::Node::ElementNotDisplayedError)
end
it "tries to drag an invisible element to a visible one" do
draggable = subject.find("//*[@id='invisible-mousedown']").first
container = subject.find("//*[@id='mouseup']").first
expect {
draggable.drag_to(container)
}.to raise_error(Capybara::Driver::Webkit::Node::ElementNotDisplayedError)
end
it "tries to drag a visible element to an invisible one" do
draggable = subject.find("//*[@id='mousedown']").first
container = subject.find("//*[@id='invisible-mouseup']").first
expect {
draggable.drag_to(container)
}.to raise_error(Capybara::Driver::Webkit::Node::ElementNotDisplayedError)
end
it "tries to select an invisible option" do
option = subject.find("//option[@id='invisible-option']").first
expect {
option.select_option
}.to raise_error(Capybara::Driver::Webkit::Node::ElementNotDisplayedError)
end
end
end
context "nesting app" do

View File

@ -1,5 +1,6 @@
require 'rspec'
require 'rspec/autorun'
require 'rbconfig'
PROJECT_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..')).freeze
@ -15,7 +16,11 @@ $:.detect do |dir|
end
end
require File.join(spec_dir,"spec_helper")
RSpec.configure do |c|
c.filter_run_excluding :skip_on_windows => !(RbConfig::CONFIG['host_os'] =~ /mingw32/).nil?
end
require File.join(spec_dir, "spec_helper")
require 'capybara/driver/webkit/browser'
$webkit_browser = Capybara::Driver::Webkit::Browser.new(:socket_class => TCPSocket, :stdout => nil)

View File

@ -6,7 +6,7 @@ class Body : public Command {
Q_OBJECT
public:
Body(WebPage *page, QObject *parent = 0);
virtual void start(QStringList &arguments);
Body(WebPage *page, QStringList &arguments, QObject *parent = 0);
virtual void start();
};

View File

@ -3,13 +3,10 @@
#include "NetworkCookieJar.h"
#include <QNetworkCookie>
ClearCookies::ClearCookies(WebPage *page, QObject *parent)
: Command(page, parent)
{ }
ClearCookies::ClearCookies(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {}
void ClearCookies::start(QStringList &arguments)
void ClearCookies::start()
{
Q_UNUSED(arguments);
NetworkCookieJar *jar = qobject_cast<NetworkCookieJar*>(page()
->networkAccessManager()
->cookieJar());

View File

@ -6,6 +6,6 @@ class ClearCookies : public Command {
Q_OBJECT;
public:
ClearCookies(WebPage *page, QObject *parent = 0);
virtual void start(QStringList &arguments);
ClearCookies(WebPage *page, QStringList &arguments, QObject *parent = 0);
virtual void start();
};

View File

@ -1,15 +1,19 @@
#include "Command.h"
#include "WebPage.h"
Command::Command(WebPage *page, QObject *parent) : QObject(parent) {
Command::Command(WebPage *page, QStringList &arguments, QObject *parent) : QObject(parent) {
m_page = page;
m_arguments = arguments;
}
void Command::start(QStringList &arguments) {
Q_UNUSED(arguments);
void Command::start() {
}
WebPage *Command::page() {
return m_page;
}
QStringList &Command::arguments() {
return m_arguments;
}

View File

@ -11,17 +11,19 @@ class Command : public QObject {
Q_OBJECT
public:
Command(WebPage *page, QObject *parent = 0);
virtual void start(QStringList &arguments);
Command(WebPage *page, QStringList &arguments, QObject *parent = 0);
virtual void start();
signals:
void finished(Response *response);
protected:
WebPage *page();
QStringList &arguments();
private:
WebPage *m_page;
QStringList m_arguments;
};

View File

@ -1,4 +1,5 @@
#include "CommandFactory.h"
#include "NullCommand.h"
#include "Visit.h"
#include "Find.h"
#include "Command.h"
@ -26,7 +27,9 @@ CommandFactory::CommandFactory(WebPage *page, QObject *parent) : QObject(parent)
m_page = page;
}
Command *CommandFactory::createCommand(const char *name) {
Command *CommandFactory::createCommand(const char *name, QStringList &arguments) {
#include "find_command.h"
return NULL;
arguments.clear();
arguments.append(QString(name));
return new NullCommand(m_page, arguments);
}

View File

@ -8,7 +8,7 @@ class CommandFactory : public QObject {
public:
CommandFactory(WebPage *page, QObject *parent = 0);
Command *createCommand(const char *name);
Command *createCommand(const char *name, QStringList &arguments);
private:
WebPage *m_page;

View File

@ -1,11 +1,14 @@
#include "CommandParser.h"
#include "CommandFactory.h"
#include "Command.h"
#include <QIODevice>
CommandParser::CommandParser(QIODevice *device, QObject *parent) :
CommandParser::CommandParser(QIODevice *device, CommandFactory *commandFactory, QObject *parent) :
QObject(parent) {
m_device = device;
m_expectingDataSize = -1;
m_commandFactory = commandFactory;
connect(m_device, SIGNAL(readyRead()), this, SLOT(checkNext()));
}
@ -60,9 +63,14 @@ void CommandParser::processArgument(const char *data) {
}
if (m_arguments.length() == m_argumentsExpected) {
emit commandReady(m_commandName, m_arguments);
m_commandName = QString();
m_arguments.clear();
m_argumentsExpected = -1;
Command *command = m_commandFactory->createCommand(m_commandName.toAscii().constData(), m_arguments);
emit commandReady(command);
reset();
}
}
void CommandParser::reset() {
m_commandName = QString();
m_arguments.clear();
m_argumentsExpected = -1;
}

View File

@ -2,28 +2,32 @@
#include <QStringList>
class QIODevice;
class CommandFactory;
class Command;
class CommandParser : public QObject {
Q_OBJECT
public:
CommandParser(QIODevice *device, QObject *parent = 0);
CommandParser(QIODevice *device, CommandFactory *commandFactory, QObject *parent = 0);
public slots:
void checkNext();
signals:
void commandReady(QString commandName, QStringList arguments);
void commandReady(Command *command);
private:
void readLine();
void readDataBlock();
void processNext(const char *line);
void processArgument(const char *data);
void reset();
QIODevice *m_device;
QString m_commandName;
QStringList m_arguments;
int m_argumentsExpected;
int m_expectingDataSize;
CommandFactory *m_commandFactory;
};

View File

@ -6,29 +6,26 @@
#include "Command.h"
#include <QTcpSocket>
#include <iostream>
Connection::Connection(QTcpSocket *socket, WebPage *page, QObject *parent) :
QObject(parent) {
m_socket = socket;
m_page = page;
m_commandParser = new CommandParser(socket, this);
m_commandFactory = new CommandFactory(page, this);
m_command = NULL;
m_commandParser = new CommandParser(socket, m_commandFactory, this);
m_runningCommand = NULL;
m_queuedCommand = NULL;
m_pageSuccess = true;
m_commandWaiting = false;
m_pageLoadingFromCommand = false;
m_pendingResponse = NULL;
connect(m_socket, SIGNAL(readyRead()), m_commandParser, SLOT(checkNext()));
connect(m_commandParser, SIGNAL(commandReady(QString, QStringList)), this, SLOT(commandReady(QString, QStringList)));
connect(m_commandParser, SIGNAL(commandReady(Command *)), this, SLOT(commandReady(Command *)));
connect(m_page, SIGNAL(pageFinished(bool)), this, SLOT(pendingLoadFinished(bool)));
}
void Connection::commandReady(QString commandName, QStringList arguments) {
m_commandName = commandName;
m_arguments = arguments;
void Connection::commandReady(Command *command) {
m_queuedCommand = command;
if (m_page->isLoading())
m_commandWaiting = true;
else
@ -38,23 +35,16 @@ void Connection::commandReady(QString commandName, QStringList arguments) {
void Connection::startCommand() {
m_commandWaiting = false;
if (m_pageSuccess) {
m_command = m_commandFactory->createCommand(m_commandName.toAscii().constData());
if (m_command) {
connect(m_page, SIGNAL(loadStarted()), this, SLOT(pageLoadingFromCommand()));
connect(m_command,
SIGNAL(finished(Response *)),
this,
SLOT(finishCommand(Response *)));
m_command->start(m_arguments);
} else {
QString failure = QString("[Capybara WebKit] Unknown command: ") + m_commandName + "\n";
writeResponse(new Response(false, failure));
}
m_commandName = QString();
m_runningCommand = m_queuedCommand;
m_queuedCommand = NULL;
connect(m_page, SIGNAL(loadStarted()), this, SLOT(pageLoadingFromCommand()));
connect(m_runningCommand,
SIGNAL(finished(Response *)),
this,
SLOT(finishCommand(Response *)));
m_runningCommand->start();
} else {
m_pageSuccess = true;
QString message = m_page->failureString();
writeResponse(new Response(false, message));
writePageLoadFailure();
}
}
@ -69,16 +59,27 @@ void Connection::pendingLoadFinished(bool success) {
if (m_pageLoadingFromCommand) {
m_pageLoadingFromCommand = false;
if (m_pendingResponse) {
writeResponse(m_pendingResponse);
m_pendingResponse = NULL;
if (m_pageSuccess) {
writeResponse(m_pendingResponse);
} else {
writePageLoadFailure();
}
}
}
}
void Connection::writePageLoadFailure() {
m_pageSuccess = true;
QString message = m_page->failureString();
writeResponse(new Response(false, message));
}
void Connection::finishCommand(Response *response) {
disconnect(m_page, SIGNAL(loadStarted()), this, SLOT(pageLoadingFromCommand()));
m_command->deleteLater();
m_command = NULL;
m_runningCommand->deleteLater();
m_runningCommand = NULL;
delete m_queuedCommand;
m_queuedCommand = NULL;
if (m_pageLoadingFromCommand)
m_pendingResponse = response;
else
@ -96,5 +97,6 @@ void Connection::writeResponse(Response *response) {
m_socket->write(messageLength.toAscii());
m_socket->write(messageUtf8);
delete response;
m_pendingResponse = NULL;
}

View File

@ -15,7 +15,7 @@ class Connection : public QObject {
Connection(QTcpSocket *socket, WebPage *page, QObject *parent = 0);
public slots:
void commandReady(QString commandName, QStringList arguments);
void commandReady(Command *command);
void finishCommand(Response *response);
void pendingLoadFinished(bool success);
void pageLoadingFromCommand();
@ -23,11 +23,11 @@ class Connection : public QObject {
private:
void startCommand();
void writeResponse(Response *response);
void writePageLoadFailure();
QTcpSocket *m_socket;
QString m_commandName;
Command *m_command;
QStringList m_arguments;
Command *m_runningCommand;
Command *m_queuedCommand;
WebPage *m_page;
CommandParser *m_commandParser;
CommandFactory *m_commandFactory;

View File

@ -1,11 +1,10 @@
#include "ConsoleMessages.h"
#include "WebPage.h"
ConsoleMessages::ConsoleMessages(WebPage *page, QObject *parent) : Command(page, parent) {
ConsoleMessages::ConsoleMessages(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
}
void ConsoleMessages::start(QStringList &arguments) {
Q_UNUSED(arguments);
void ConsoleMessages::start() {
emit finished(new Response(true, page()->consoleMessages()));
}

View File

@ -6,7 +6,7 @@ class ConsoleMessages : public Command {
Q_OBJECT
public:
ConsoleMessages(WebPage *page, QObject *parent = 0);
virtual void start(QStringList &arguments);
ConsoleMessages(WebPage *page, QStringList &arguments, QObject *parent = 0);
virtual void start();
};

View File

@ -1,7 +1,7 @@
#include "CurrentUrl.h"
#include "WebPage.h"
CurrentUrl::CurrentUrl(WebPage *page, QObject *parent) : Command(page, parent) {
CurrentUrl::CurrentUrl(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
}
/*
@ -51,9 +51,7 @@ CurrentUrl::CurrentUrl(WebPage *page, QObject *parent) : Command(page, parent) {
* redirect w/o pushState, in which case QWebFrame->url() will have the correct
* current_url value. In all other cases QWebFrame->requestedUrl() is correct.
*/
void CurrentUrl::start(QStringList &arguments) {
Q_UNUSED(arguments);
void CurrentUrl::start() {
QUrl humanUrl = wasRedirectedAndNotModifiedByJavascript() ?
page()->currentFrame()->url() : page()->currentFrame()->requestedUrl();
QByteArray encodedBytes = humanUrl.toEncoded();

View File

@ -6,8 +6,8 @@ class CurrentUrl : public Command {
Q_OBJECT
public:
CurrentUrl(WebPage *page, QObject *parent = 0);
virtual void start(QStringList &arguments);
CurrentUrl(WebPage *page, QStringList &arguments, QObject *parent = 0);
virtual void start();
private:
bool wasRegularLoad();

View File

@ -2,12 +2,12 @@
#include "WebPage.h"
#include <iostream>
Evaluate::Evaluate(WebPage *page, QObject *parent) : Command(page, parent) {
Evaluate::Evaluate(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
m_buffer = "";
}
void Evaluate::start(QStringList &arguments) {
QVariant result = page()->currentFrame()->evaluateJavaScript(arguments[0]);
void Evaluate::start() {
QVariant result = page()->currentFrame()->evaluateJavaScript(arguments()[0]);
addVariant(result);
emit finished(new Response(true, m_buffer));
}

View File

@ -8,8 +8,8 @@ class Evaluate : public Command {
Q_OBJECT
public:
Evaluate(WebPage *page, QObject *parent = 0);
virtual void start(QStringList &arguments);
Evaluate(WebPage *page, QStringList &arguments, QObject *parent = 0);
virtual void start();
private:
void addVariant(QVariant &object);

View File

@ -1,11 +1,11 @@
#include "Execute.h"
#include "WebPage.h"
Execute::Execute(WebPage *page, QObject *parent) : Command(page, parent) {
Execute::Execute(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
}
void Execute::start(QStringList &arguments) {
QString script = arguments[0] + QString("; 'success'");
void Execute::start() {
QString script = arguments()[0] + QString("; 'success'");
QVariant result = page()->currentFrame()->evaluateJavaScript(script);
if (result.isValid()) {
emit finished(new Response(true));

View File

@ -6,7 +6,7 @@ class Execute : public Command {
Q_OBJECT
public:
Execute(WebPage *page, QObject *parent = 0);
virtual void start(QStringList &arguments);
Execute(WebPage *page, QStringList &arguments, QObject *parent = 0);
virtual void start();
};

View File

@ -2,12 +2,12 @@
#include "Command.h"
#include "WebPage.h"
Find::Find(WebPage *page, QObject *parent) : Command(page, parent) {
Find::Find(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
}
void Find::start(QStringList &arguments) {
void Find::start() {
QString message;
QVariant result = page()->invokeCapybaraFunction("find", arguments);
QVariant result = page()->invokeCapybaraFunction("find", arguments());
if (result.isValid()) {
message = result.toString();

View File

@ -6,8 +6,8 @@ class Find : public Command {
Q_OBJECT
public:
Find(WebPage *page, QObject *parent = 0);
virtual void start(QStringList &arguments);
Find(WebPage *page, QStringList &arguments, QObject *parent = 0);
virtual void start();
};

View File

@ -2,17 +2,17 @@
#include "Command.h"
#include "WebPage.h"
FrameFocus::FrameFocus(WebPage *page, QObject *parent) : Command(page, parent) {
FrameFocus::FrameFocus(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
}
void FrameFocus::start(QStringList &arguments) {
void FrameFocus::start() {
findFrames();
switch(arguments.length()) {
switch(arguments().length()) {
case 1:
focusId(arguments[0]);
focusId(arguments()[0]);
break;
case 2:
focusIndex(arguments[1].toInt());
focusIndex(arguments()[1].toInt());
break;
default:
focusParent();

View File

@ -7,8 +7,8 @@ class FrameFocus : public Command {
Q_OBJECT
public:
FrameFocus(WebPage *page, QObject *parent = 0);
virtual void start(QStringList &arguments);
FrameFocus(WebPage *page, QStringList &arguments, QObject *parent = 0);
virtual void start();
private:
void findFrames();

View File

@ -2,15 +2,13 @@
#include "WebPage.h"
#include "NetworkCookieJar.h"
GetCookies::GetCookies(WebPage *page, QObject *parent)
: Command(page, parent)
GetCookies::GetCookies(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent)
{
m_buffer = "";
}
void GetCookies::start(QStringList &arguments)
void GetCookies::start()
{
Q_UNUSED(arguments);
NetworkCookieJar *jar = qobject_cast<NetworkCookieJar*>(page()
->networkAccessManager()
->cookieJar());

View File

@ -6,8 +6,8 @@ class GetCookies : public Command {
Q_OBJECT;
public:
GetCookies(WebPage *page, QObject *parent = 0);
virtual void start(QStringList &arguments);
GetCookies(WebPage *page, QStringList &arguments, QObject *parent = 0);
virtual void start();
private:
QString m_buffer;

View File

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

View File

@ -6,6 +6,6 @@ class Header : public Command {
Q_OBJECT
public:
Header(WebPage *page, QObject *parent = 0);
virtual void start(QStringList &arguments);
Header(WebPage *page, QStringList &arguments, QObject *parent = 0);
virtual void start();
};

View File

@ -1,11 +1,10 @@
#include "Headers.h"
#include "WebPage.h"
Headers::Headers(WebPage *page, QObject *parent) : Command(page, parent) {
Headers::Headers(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
}
void Headers::start(QStringList &arguments) {
Q_UNUSED(arguments);
void Headers::start() {
emit finished(new Response(true, page()->pageHeaders()));
}

View File

@ -6,7 +6,7 @@ class Headers : public Command {
Q_OBJECT
public:
Headers(WebPage *page, QObject *parent = 0);
virtual void start(QStringList &arguments);
Headers(WebPage *page, QStringList &arguments, QObject *parent = 0);
virtual void start();
};

View File

@ -1,11 +1,11 @@
#include "Node.h"
#include "WebPage.h"
Node::Node(WebPage *page, QObject *parent) : Command(page, parent) {
Node::Node(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
}
void Node::start(QStringList &arguments) {
QStringList functionArguments(arguments);
void Node::start() {
QStringList functionArguments(arguments());
QString functionName = functionArguments.takeFirst();
QVariant result = page()->invokeCapybaraFunction(functionName, functionArguments);
QString attributeValue = result.toString();

View File

@ -7,7 +7,7 @@ class Node : public Command {
Q_OBJECT
public:
Node(WebPage *page, QObject *parent = 0);
virtual void start(QStringList &arguments);
Node(WebPage *page, QStringList &arguments, QObject *parent = 0);
virtual void start();
};

10
src/NullCommand.cpp Normal file
View File

@ -0,0 +1,10 @@
#include "NullCommand.h"
#include "WebPage.h"
NullCommand::NullCommand(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {}
void NullCommand::start() {
QString failure = QString("[Capybara WebKit] Unknown command: ") + arguments()[0] + "\n";
emit finished(new Response(false, failure));
}

11
src/NullCommand.h Normal file
View File

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

View File

@ -1,14 +1,13 @@
#include "Render.h"
#include "WebPage.h"
Render::Render(WebPage *page, QObject *parent) : Command(page, parent) {
Render::Render(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
}
void Render::start(QStringList &arguments) {
QStringList functionArguments(arguments);
QString imagePath = functionArguments.takeFirst();
int width = functionArguments.takeFirst().toInt();
int height = functionArguments.takeFirst().toInt();
void Render::start() {
QString imagePath = arguments()[0];
int width = arguments()[1].toInt();
int height = arguments()[2].toInt();
QSize size(width, height);
page()->setViewportSize(size);

View File

@ -7,6 +7,6 @@ class Render : public Command {
Q_OBJECT
public:
Render(WebPage *page, QObject *parent = 0);
virtual void start(QStringList &arguments);
Render(WebPage *page, QStringList &arguments, QObject *parent = 0);
virtual void start();
};

View File

@ -1,12 +1,10 @@
#include "RequestedUrl.h"
#include "WebPage.h"
RequestedUrl::RequestedUrl(WebPage *page, QObject *parent) : Command(page, parent) {
RequestedUrl::RequestedUrl(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
}
void RequestedUrl::start(QStringList &arguments) {
Q_UNUSED(arguments);
void RequestedUrl::start() {
QUrl humanUrl = page()->currentFrame()->requestedUrl();
QByteArray encodedBytes = humanUrl.toEncoded();
QString urlString = QString(encodedBytes);

View File

@ -6,7 +6,7 @@ class RequestedUrl : public Command {
Q_OBJECT
public:
RequestedUrl(WebPage *page, QObject *parent = 0);
virtual void start(QStringList &arguments);
RequestedUrl(WebPage *page, QStringList &arguments, QObject *parent = 0);
virtual void start();
};

View File

@ -3,14 +3,11 @@
#include "NetworkAccessManager.h"
#include "NetworkCookieJar.h"
Reset::Reset(WebPage *page, QObject *parent) : Command(page, parent) {
Reset::Reset(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
}
void Reset::start(QStringList &arguments) {
Q_UNUSED(arguments);
void Reset::start() {
page()->triggerAction(QWebPage::Stop);
page()->currentFrame()->setHtml("<html><body></body></html>");
page()->networkAccessManager()->setCookieJar(new NetworkCookieJar());
page()->setCustomNetworkAccessManager();
page()->setUserAgent(NULL);

View File

@ -6,8 +6,8 @@ class Reset : public Command {
Q_OBJECT
public:
Reset(WebPage *page, QObject *parent = 0);
virtual void start(QStringList &arguments);
Reset(WebPage *page, QStringList &arguments, QObject *parent = 0);
virtual void start();
private:
void resetHistory();

View File

@ -12,7 +12,7 @@ Server::Server(QObject *parent, bool ignoreSslErrors) : QObject(parent) {
bool Server::start() {
connect(m_tcp_server, SIGNAL(newConnection()), this, SLOT(handleConnection()));
return m_tcp_server->listen(QHostAddress::Any, 0);
return m_tcp_server->listen(QHostAddress::LocalHost, 0);
}
quint16 Server::server_port() const {

View File

@ -3,13 +3,11 @@
#include "NetworkCookieJar.h"
#include <QNetworkCookie>
SetCookie::SetCookie(WebPage *page, QObject *parent)
: Command(page, parent)
{ }
SetCookie::SetCookie(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {}
void SetCookie::start(QStringList &arguments)
void SetCookie::start()
{
QList<QNetworkCookie> cookies = QNetworkCookie::parseCookies(arguments[0].toAscii());
QList<QNetworkCookie> cookies = QNetworkCookie::parseCookies(arguments()[0].toAscii());
NetworkCookieJar *jar = qobject_cast<NetworkCookieJar*>(page()
->networkAccessManager()
->cookieJar());

View File

@ -6,6 +6,6 @@ class SetCookie : public Command {
Q_OBJECT;
public:
SetCookie(WebPage *page, QObject *parent = 0);
virtual void start(QStringList &arguments);
SetCookie(WebPage *page, QStringList &arguments, QObject *parent = 0);
virtual void start();
};

View File

@ -3,21 +3,19 @@
#include <QNetworkAccessManager>
#include <QNetworkProxy>
SetProxy::SetProxy(WebPage *page, QObject *parent)
: Command(page, parent)
{ }
SetProxy::SetProxy(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {}
void SetProxy::start(QStringList &arguments)
void SetProxy::start()
{
// default to empty proxy
QNetworkProxy proxy;
if (arguments.size() > 0)
if (arguments().size() > 0)
proxy = QNetworkProxy(QNetworkProxy::HttpProxy,
arguments[0],
(quint16)(arguments[1].toInt()),
arguments[2],
arguments[3]);
arguments()[0],
(quint16)(arguments()[1].toInt()),
arguments()[2],
arguments()[3]);
page()->networkAccessManager()->setProxy(proxy);
emit finished(new Response(true));

View File

@ -6,6 +6,6 @@ class SetProxy : public Command {
Q_OBJECT;
public:
SetProxy(WebPage *page, QObject *parent = 0);
virtual void start(QStringList &arguments);
SetProxy(WebPage *page, QStringList &arguments, QObject *parent = 0);
virtual void start();
};

View File

@ -1,12 +1,10 @@
#include "Source.h"
#include "WebPage.h"
Source::Source(WebPage *page, QObject *parent) : Command(page, parent) {
Source::Source(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
}
void Source::start(QStringList &arguments) {
Q_UNUSED(arguments)
void Source::start() {
QNetworkAccessManager* accessManager = page()->networkAccessManager();
QNetworkRequest request(page()->currentFrame()->url());
reply = accessManager->get(request);

View File

@ -7,8 +7,8 @@ class Source : public Command {
Q_OBJECT
public:
Source(WebPage *page, QObject *parent = 0);
virtual void start(QStringList &arguments);
Source(WebPage *page, QStringList &arguments, QObject *parent = 0);
virtual void start();
public slots:
void sourceLoaded();

View File

@ -2,11 +2,10 @@
#include "WebPage.h"
#include <sstream>
Status::Status(WebPage *page, QObject *parent) : Command(page, parent) {
Status::Status(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
}
void Status::start(QStringList &arguments) {
Q_UNUSED(arguments);
void Status::start() {
int status = page()->getLastStatus();
emit finished(new Response(true, QString::number(status)));
}

View File

@ -6,7 +6,7 @@ class Status : public Command {
Q_OBJECT
public:
Status(WebPage *page, QObject *parent = 0);
virtual void start(QStringList &arguments);
Status(WebPage *page, QStringList &arguments, QObject *parent = 0);
virtual void start();
};

View File

@ -1,12 +1,10 @@
#include "Url.h"
#include "WebPage.h"
Url::Url(WebPage *page, QObject *parent) : Command(page, parent) {
Url::Url(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
}
void Url::start(QStringList &argments) {
Q_UNUSED(argments);
void Url::start() {
QUrl humanUrl = page()->currentFrame()->url();
QByteArray encodedBytes = humanUrl.toEncoded();
QString urlString = QString(encodedBytes);

View File

@ -6,7 +6,7 @@ class Url : public Command {
Q_OBJECT
public:
Url(WebPage *page, QObject *parent = 0);
virtual void start(QStringList &argments);
Url(WebPage *page, QStringList &arguments, QObject *parent = 0);
virtual void start();
};

View File

@ -2,20 +2,11 @@
#include "Command.h"
#include "WebPage.h"
Visit::Visit(WebPage *page, QObject *parent) : Command(page, parent) {
connect(page, SIGNAL(pageFinished(bool)), this, SLOT(loadFinished(bool)));
Visit::Visit(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
}
void Visit::start(QStringList &arguments) {
QUrl requestedUrl = QUrl::fromEncoded(arguments[0].toUtf8(), QUrl::StrictMode);
void Visit::start() {
QUrl requestedUrl = QUrl::fromEncoded(arguments()[0].toUtf8(), QUrl::StrictMode);
page()->currentFrame()->load(QUrl(requestedUrl));
}
void Visit::loadFinished(bool success) {
QString message;
if (!success)
message = page()->failureString();
disconnect(page(), SIGNAL(pageFinished(bool)), this, SLOT(loadFinished(bool)));
emit finished(new Response(success, message));
emit finished(new Response(true));
}

View File

@ -6,10 +6,7 @@ class Visit : public Command {
Q_OBJECT
public:
Visit(WebPage *page, QObject *parent = 0);
virtual void start(QStringList &arguments);
private slots:
void loadFinished(bool success);
Visit(WebPage *page, QStringList &arguments, QObject *parent = 0);
virtual void start();
};

View File

@ -1,11 +1,10 @@
#include "Body.h"
#include "WebPage.h"
Body::Body(WebPage *page, QObject *parent) : Command(page, parent) {
Body::Body(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
}
void Body::start(QStringList &arguments) {
Q_UNUSED(arguments);
void Body::start() {
QString result = page()->currentFrame()->toHtml();
emit finished(new Response(true, result));
}

View File

@ -230,6 +230,7 @@ Capybara = {
this.keyupdown(index, "keydown", keyCode);
this.keypress(index, false, false, false, false, value.charCodeAt(strindex), value.charCodeAt(strindex));
this.keyupdown(index, "keyup", keyCode);
this.trigger(index, "input");
}
this.trigger(index, "change");
this.trigger(index, "blur");

View File

@ -1,6 +1,6 @@
#define CHECK_COMMAND(expectedName) \
if (strcmp(#expectedName, name) == 0) { \
return new expectedName(m_page, this); \
return new expectedName(m_page, arguments, this); \
}
CHECK_COMMAND(Visit)

View File

@ -34,6 +34,7 @@ HEADERS = \
CommandParser.h \
CommandFactory.h \
SetProxy.h \
NullCommand.h \
SOURCES = \
CurrentUrl.cpp \
@ -69,6 +70,7 @@ SOURCES = \
CommandParser.cpp \
CommandFactory.cpp \
SetProxy.cpp \
NullCommand.cpp \
RESOURCES = webkit_server.qrc
QT += network webkit