diff --git a/.gitignore b/.gitignore index c7bb96b..00c4d20 100644 --- a/.gitignore +++ b/.gitignore @@ -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 \ No newline at end of file diff --git a/ChangeLog b/ChangeLog index 17b981e..707fcf6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2012-03-09 Joe Ferris + * node.rb, driver_spec.rb: Allow interaction with invisible elements + +2012-03-02 Joe Ferris + * browser.rb: Use Timeout from stdlib since Capybara.timeout is being removed + 2012-03-02 Matthew Mongeau * capybara_webkit_builder.rb: set LANG to en_US.UTF-8 to prevent string encoding issues during install diff --git a/Gemfile.lock b/Gemfile.lock index cf45214..ed69d55 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -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) diff --git a/NEWS.md b/NEWS.md index c6c5915..5418488 100644 --- a/NEWS.md +++ b/NEWS.md @@ -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. diff --git a/README.md b/README.md index ef10e3b..3b943a6 100644 --- a/README.md +++ b/README.md @@ -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 ---------------- diff --git a/lib/capybara/driver/webkit/browser.rb b/lib/capybara/driver/webkit/browser.rb index 1673812..9d0c2fc 100644 --- a/lib/capybara/driver/webkit/browser.rb +++ b/lib/capybara/driver/webkit/browser.rb @@ -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 diff --git a/lib/capybara/driver/webkit/node.rb b/lib/capybara/driver/webkit/node.rb index ddfcf67..bbb9a3c 100644 --- a/lib/capybara/driver/webkit/node.rb +++ b/lib/capybara/driver/webkit/node.rb @@ -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 diff --git a/lib/capybara/driver/webkit/version.rb b/lib/capybara/driver/webkit/version.rb index 2837d50..b12f766 100644 --- a/lib/capybara/driver/webkit/version.rb +++ b/lib/capybara/driver/webkit/version.rb @@ -1,7 +1,7 @@ module Capybara module Driver class Webkit - VERSION = '0.10.1'.freeze + VERSION = '0.11.0'.freeze end end end diff --git a/lib/capybara/webkit/matchers.rb b/lib/capybara/webkit/matchers.rb index a0af3c0..715d605 100644 --- a/lib/capybara/webkit/matchers.rb +++ b/lib/capybara/webkit/matchers.rb @@ -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 diff --git a/lib/capybara_webkit_builder.rb b/lib/capybara_webkit_builder.rb index 1ff8148..68aaa6e 100644 --- a/lib/capybara_webkit_builder.rb +++ b/lib/capybara_webkit_builder.rb @@ -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 diff --git a/spec/browser_spec.rb b/spec/browser_spec.rb index 0f133ac..783b566 100644 --- a/spec/browser_spec.rb +++ b/spec/browser_spec.rb @@ -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 {} diff --git a/spec/driver_spec.rb b/spec/driver_spec.rb index b6be065..67cb7dc 100644 --- a/spec/driver_spec.rb +++ b/spec/driver_spec.rb @@ -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
Change me
Push me
Release me
- -
Next - 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 diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 2a35c71..89a1361 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -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) diff --git a/src/Body.h b/src/Body.h index 66fd34a..54e4d03 100644 --- a/src/Body.h +++ b/src/Body.h @@ -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(); }; diff --git a/src/ClearCookies.cpp b/src/ClearCookies.cpp index 048e877..6ceaa22 100644 --- a/src/ClearCookies.cpp +++ b/src/ClearCookies.cpp @@ -3,13 +3,10 @@ #include "NetworkCookieJar.h" #include -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(page() ->networkAccessManager() ->cookieJar()); diff --git a/src/ClearCookies.h b/src/ClearCookies.h index 0a1841a..ab8ba87 100644 --- a/src/ClearCookies.h +++ b/src/ClearCookies.h @@ -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(); }; diff --git a/src/Command.cpp b/src/Command.cpp index 6fdd77e..e7275f9 100644 --- a/src/Command.cpp +++ b/src/Command.cpp @@ -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; +} + diff --git a/src/Command.h b/src/Command.h index 3db21f6..3c81295 100644 --- a/src/Command.h +++ b/src/Command.h @@ -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; }; diff --git a/src/CommandFactory.cpp b/src/CommandFactory.cpp index c35a01e..78d6b61 100644 --- a/src/CommandFactory.cpp +++ b/src/CommandFactory.cpp @@ -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); } diff --git a/src/CommandFactory.h b/src/CommandFactory.h index c52b8d6..bc49bce 100644 --- a/src/CommandFactory.h +++ b/src/CommandFactory.h @@ -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; diff --git a/src/CommandParser.cpp b/src/CommandParser.cpp index bc2520f..1a0562b 100644 --- a/src/CommandParser.cpp +++ b/src/CommandParser.cpp @@ -1,11 +1,14 @@ #include "CommandParser.h" +#include "CommandFactory.h" +#include "Command.h" #include -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; +} diff --git a/src/CommandParser.h b/src/CommandParser.h index 54d43be..19f7ec8 100644 --- a/src/CommandParser.h +++ b/src/CommandParser.h @@ -2,28 +2,32 @@ #include 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; }; diff --git a/src/Connection.cpp b/src/Connection.cpp index c798f6d..2e6e114 100644 --- a/src/Connection.cpp +++ b/src/Connection.cpp @@ -6,29 +6,26 @@ #include "Command.h" #include -#include 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; } diff --git a/src/Connection.h b/src/Connection.h index e6682e0..56bfb23 100644 --- a/src/Connection.h +++ b/src/Connection.h @@ -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; diff --git a/src/ConsoleMessages.cpp b/src/ConsoleMessages.cpp index 5756eee..5e1b151 100644 --- a/src/ConsoleMessages.cpp +++ b/src/ConsoleMessages.cpp @@ -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())); } diff --git a/src/ConsoleMessages.h b/src/ConsoleMessages.h index 37dd1f5..633d85a 100644 --- a/src/ConsoleMessages.h +++ b/src/ConsoleMessages.h @@ -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(); }; diff --git a/src/CurrentUrl.cpp b/src/CurrentUrl.cpp index 1664f0d..9508aa1 100644 --- a/src/CurrentUrl.cpp +++ b/src/CurrentUrl.cpp @@ -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(); diff --git a/src/CurrentUrl.h b/src/CurrentUrl.h index 1db07bd..613f5d5 100644 --- a/src/CurrentUrl.h +++ b/src/CurrentUrl.h @@ -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(); diff --git a/src/Evaluate.cpp b/src/Evaluate.cpp index a8cb751..3090e73 100644 --- a/src/Evaluate.cpp +++ b/src/Evaluate.cpp @@ -2,12 +2,12 @@ #include "WebPage.h" #include -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)); } diff --git a/src/Evaluate.h b/src/Evaluate.h index f513205..883d89c 100644 --- a/src/Evaluate.h +++ b/src/Evaluate.h @@ -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); diff --git a/src/Execute.cpp b/src/Execute.cpp index f21f7c2..2a2b5bb 100644 --- a/src/Execute.cpp +++ b/src/Execute.cpp @@ -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)); diff --git a/src/Execute.h b/src/Execute.h index b76a092..c9b06f5 100644 --- a/src/Execute.h +++ b/src/Execute.h @@ -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(); }; diff --git a/src/Find.cpp b/src/Find.cpp index 1ed7f2a..3ccd186 100644 --- a/src/Find.cpp +++ b/src/Find.cpp @@ -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(); diff --git a/src/Find.h b/src/Find.h index 91ce0de..ad27a8b 100644 --- a/src/Find.h +++ b/src/Find.h @@ -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(); }; diff --git a/src/FrameFocus.cpp b/src/FrameFocus.cpp index f120520..4e7b364 100644 --- a/src/FrameFocus.cpp +++ b/src/FrameFocus.cpp @@ -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(); diff --git a/src/FrameFocus.h b/src/FrameFocus.h index 96a57d2..effe17e 100644 --- a/src/FrameFocus.h +++ b/src/FrameFocus.h @@ -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(); diff --git a/src/GetCookies.cpp b/src/GetCookies.cpp index ecf3097..91a1186 100644 --- a/src/GetCookies.cpp +++ b/src/GetCookies.cpp @@ -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(page() ->networkAccessManager() ->cookieJar()); diff --git a/src/GetCookies.h b/src/GetCookies.h index d98f844..069815f 100644 --- a/src/GetCookies.h +++ b/src/GetCookies.h @@ -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; diff --git a/src/Header.cpp b/src/Header.cpp index 3d53f55..ef42d7a 100644 --- a/src/Header.cpp +++ b/src/Header.cpp @@ -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(page()->networkAccessManager()); if (key.toLower().replace("-", "_") == "user_agent") { page()->setUserAgent(value); diff --git a/src/Header.h b/src/Header.h index 90289b1..ede37b5 100644 --- a/src/Header.h +++ b/src/Header.h @@ -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(); }; diff --git a/src/Headers.cpp b/src/Headers.cpp index 1ffab85..6fe364c 100644 --- a/src/Headers.cpp +++ b/src/Headers.cpp @@ -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())); } diff --git a/src/Headers.h b/src/Headers.h index 72d4b28..69237b6 100644 --- a/src/Headers.h +++ b/src/Headers.h @@ -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(); }; diff --git a/src/Node.cpp b/src/Node.cpp index 54bad1c..f9e7102 100644 --- a/src/Node.cpp +++ b/src/Node.cpp @@ -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(); diff --git a/src/Node.h b/src/Node.h index 146a2f1..b136e44 100644 --- a/src/Node.h +++ b/src/Node.h @@ -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(); }; diff --git a/src/NullCommand.cpp b/src/NullCommand.cpp new file mode 100644 index 0000000..c3ec9b7 --- /dev/null +++ b/src/NullCommand.cpp @@ -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)); +} + diff --git a/src/NullCommand.h b/src/NullCommand.h new file mode 100644 index 0000000..6296210 --- /dev/null +++ b/src/NullCommand.h @@ -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(); +}; diff --git a/src/Render.cpp b/src/Render.cpp index 4c25a97..930917c 100644 --- a/src/Render.cpp +++ b/src/Render.cpp @@ -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); diff --git a/src/Render.h b/src/Render.h index b433d4d..6abb36e 100644 --- a/src/Render.h +++ b/src/Render.h @@ -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(); }; diff --git a/src/RequestedUrl.cpp b/src/RequestedUrl.cpp index 4f7bf93..ad64d18 100644 --- a/src/RequestedUrl.cpp +++ b/src/RequestedUrl.cpp @@ -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); diff --git a/src/RequestedUrl.h b/src/RequestedUrl.h index e90a1dc..6209f38 100644 --- a/src/RequestedUrl.h +++ b/src/RequestedUrl.h @@ -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(); }; diff --git a/src/Reset.cpp b/src/Reset.cpp index b4ad3ef..d42a408 100644 --- a/src/Reset.cpp +++ b/src/Reset.cpp @@ -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(""); page()->networkAccessManager()->setCookieJar(new NetworkCookieJar()); page()->setCustomNetworkAccessManager(); page()->setUserAgent(NULL); diff --git a/src/Reset.h b/src/Reset.h index 8e2cef0..e2b0b4b 100644 --- a/src/Reset.h +++ b/src/Reset.h @@ -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(); diff --git a/src/Server.cpp b/src/Server.cpp index d7ab4c1..401a2ee 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -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 { diff --git a/src/SetCookie.cpp b/src/SetCookie.cpp index 3b2fd9d..e239d10 100644 --- a/src/SetCookie.cpp +++ b/src/SetCookie.cpp @@ -3,13 +3,11 @@ #include "NetworkCookieJar.h" #include -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 cookies = QNetworkCookie::parseCookies(arguments[0].toAscii()); + QList cookies = QNetworkCookie::parseCookies(arguments()[0].toAscii()); NetworkCookieJar *jar = qobject_cast(page() ->networkAccessManager() ->cookieJar()); diff --git a/src/SetCookie.h b/src/SetCookie.h index 8959c79..d6070f3 100644 --- a/src/SetCookie.h +++ b/src/SetCookie.h @@ -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(); }; diff --git a/src/SetProxy.cpp b/src/SetProxy.cpp index 12742f2..73c72a3 100644 --- a/src/SetProxy.cpp +++ b/src/SetProxy.cpp @@ -3,21 +3,19 @@ #include #include -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)); diff --git a/src/SetProxy.h b/src/SetProxy.h index b9c154a..cff3a74 100644 --- a/src/SetProxy.h +++ b/src/SetProxy.h @@ -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(); }; diff --git a/src/Source.cpp b/src/Source.cpp index 698d4e5..dd4cdd4 100644 --- a/src/Source.cpp +++ b/src/Source.cpp @@ -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); diff --git a/src/Source.h b/src/Source.h index 9925948..982a155 100644 --- a/src/Source.h +++ b/src/Source.h @@ -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(); diff --git a/src/Status.cpp b/src/Status.cpp index c281e36..7b76258 100644 --- a/src/Status.cpp +++ b/src/Status.cpp @@ -2,11 +2,10 @@ #include "WebPage.h" #include -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))); } diff --git a/src/Status.h b/src/Status.h index e44850f..241b48e 100644 --- a/src/Status.h +++ b/src/Status.h @@ -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(); }; diff --git a/src/Url.cpp b/src/Url.cpp index d326568..fd6fc0d 100644 --- a/src/Url.cpp +++ b/src/Url.cpp @@ -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); diff --git a/src/Url.h b/src/Url.h index 180f2e0..768f2d8 100644 --- a/src/Url.h +++ b/src/Url.h @@ -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(); }; diff --git a/src/Visit.cpp b/src/Visit.cpp index 2e819f3..d069097 100644 --- a/src/Visit.cpp +++ b/src/Visit.cpp @@ -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)); } diff --git a/src/Visit.h b/src/Visit.h index 5e6d148..75ef7a6 100644 --- a/src/Visit.h +++ b/src/Visit.h @@ -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(); }; diff --git a/src/body.cpp b/src/body.cpp index b41311e..469b75e 100644 --- a/src/body.cpp +++ b/src/body.cpp @@ -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)); } diff --git a/src/capybara.js b/src/capybara.js index 6ecb0e4..1e2f859 100644 --- a/src/capybara.js +++ b/src/capybara.js @@ -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"); diff --git a/src/find_command.h b/src/find_command.h index 4298941..8f35e07 100644 --- a/src/find_command.h +++ b/src/find_command.h @@ -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) diff --git a/src/webkit_server.pro b/src/webkit_server.pro index 8f0c8e4..8e7e0c0 100644 --- a/src/webkit_server.pro +++ b/src/webkit_server.pro @@ -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