capybara-webkit 0.12.1 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -1
- data/GOALS +9 -0
- data/Gemfile.lock +15 -12
- data/LICENSE +1 -1
- data/NEWS.md +18 -0
- data/README.md +81 -2
- data/capybara-webkit.gemspec +1 -1
- data/lib/capybara/webkit.rb +11 -6
- data/lib/capybara/{driver/webkit → webkit}/browser.rb +90 -4
- data/lib/capybara/{driver/webkit → webkit}/connection.rb +48 -47
- data/lib/capybara/{driver/webkit → webkit}/cookie_jar.rb +1 -1
- data/lib/capybara/webkit/driver.rb +186 -0
- data/lib/capybara/webkit/errors.rb +10 -0
- data/lib/capybara/{driver/webkit → webkit}/node.rb +12 -4
- data/lib/capybara/{driver/webkit → webkit}/socket_debugger.rb +4 -1
- data/lib/capybara/{driver/webkit → webkit}/version.rb +1 -1
- data/lib/capybara_webkit_builder.rb +17 -3
- data/spec/browser_spec.rb +95 -7
- data/spec/connection_spec.rb +16 -5
- data/spec/cookie_jar_spec.rb +3 -3
- data/spec/driver_rendering_spec.rb +19 -26
- data/spec/driver_resize_window_spec.rb +3 -3
- data/spec/driver_spec.rb +1200 -822
- data/spec/integration/driver_spec.rb +4 -3
- data/spec/selenium_compatibility_spec.rb +49 -0
- data/spec/spec_helper.rb +14 -6
- data/spec/support/app_runner.rb +94 -0
- data/src/Authenticate.cpp +18 -0
- data/src/Authenticate.h +12 -0
- data/src/Body.h +3 -5
- data/src/ClearCookies.cpp +3 -5
- data/src/ClearCookies.h +3 -5
- data/src/ClearPromptText.cpp +11 -0
- data/src/ClearPromptText.h +9 -0
- data/src/Command.cpp +4 -15
- data/src/Command.h +3 -14
- data/src/CommandFactory.cpp +20 -6
- data/src/CommandFactory.h +3 -2
- data/src/CommandParser.cpp +1 -1
- data/src/Connection.cpp +22 -21
- data/src/Connection.h +5 -6
- data/src/ConsoleMessages.cpp +2 -1
- data/src/ConsoleMessages.h +3 -5
- data/src/CurrentUrl.cpp +9 -48
- data/src/CurrentUrl.h +8 -8
- data/src/EnableLogging.cpp +10 -0
- data/src/EnableLogging.h +12 -0
- data/src/Evaluate.cpp +2 -1
- data/src/Evaluate.h +3 -5
- data/src/Execute.cpp +2 -1
- data/src/Execute.h +3 -5
- data/src/Find.cpp +3 -2
- data/src/Find.h +3 -5
- data/src/FrameFocus.cpp +3 -2
- data/src/FrameFocus.h +3 -4
- data/src/GetCookies.cpp +3 -4
- data/src/GetCookies.h +3 -5
- data/src/GetTimeout.cpp +9 -0
- data/src/GetTimeout.h +11 -0
- data/src/GetWindowHandle.cpp +11 -0
- data/src/GetWindowHandle.h +10 -0
- data/src/GetWindowHandles.cpp +20 -0
- data/src/GetWindowHandles.h +10 -0
- data/src/Header.cpp +2 -1
- data/src/Header.h +3 -5
- data/src/Headers.cpp +8 -2
- data/src/Headers.h +3 -5
- data/src/IgnoreSslErrors.cpp +4 -3
- data/src/IgnoreSslErrors.h +3 -5
- data/src/JavascriptAlertMessages.cpp +10 -0
- data/src/JavascriptAlertMessages.h +9 -0
- data/src/JavascriptConfirmMessages.cpp +10 -0
- data/src/JavascriptConfirmMessages.h +9 -0
- data/src/JavascriptInvocation.cpp +1 -1
- data/src/JavascriptInvocation.h +1 -1
- data/src/JavascriptPromptMessages.cpp +10 -0
- data/src/JavascriptPromptMessages.h +9 -0
- data/src/NetworkAccessManager.cpp +38 -5
- data/src/NetworkAccessManager.h +20 -0
- data/src/Node.cpp +6 -1
- data/src/Node.h +4 -5
- data/src/NullCommand.cpp +5 -2
- data/src/NullCommand.h +4 -3
- data/src/PageLoadingCommand.cpp +12 -7
- data/src/PageLoadingCommand.h +6 -9
- data/src/Render.cpp +2 -1
- data/src/Render.h +3 -5
- data/src/RequestedUrl.cpp +2 -1
- data/src/RequestedUrl.h +3 -5
- data/src/Reset.cpp +3 -17
- data/src/Reset.h +3 -8
- data/src/ResizeWindow.cpp +2 -1
- data/src/ResizeWindow.h +3 -5
- data/src/Response.cpp +4 -0
- data/src/Response.h +1 -0
- data/src/Server.cpp +2 -3
- data/src/Server.h +0 -2
- data/src/SetConfirmAction.cpp +11 -0
- data/src/SetConfirmAction.h +9 -0
- data/src/SetCookie.cpp +3 -4
- data/src/SetCookie.h +3 -5
- data/src/SetPromptAction.cpp +11 -0
- data/src/SetPromptAction.h +9 -0
- data/src/SetPromptText.cpp +11 -0
- data/src/SetPromptText.h +9 -0
- data/src/SetProxy.cpp +2 -1
- data/src/SetProxy.h +3 -5
- data/src/SetSkipImageLoading.cpp +12 -0
- data/src/SetSkipImageLoading.h +9 -0
- data/src/SetTimeout.cpp +19 -0
- data/src/SetTimeout.h +9 -0
- data/src/SocketCommand.cpp +21 -0
- data/src/SocketCommand.h +29 -0
- data/src/Source.cpp +3 -2
- data/src/Source.h +3 -4
- data/src/Status.cpp +2 -1
- data/src/Status.h +3 -5
- data/src/TimeoutCommand.cpp +69 -0
- data/src/TimeoutCommand.h +41 -0
- data/src/UnsupportedContentHandler.cpp +11 -17
- data/src/UnsupportedContentHandler.h +5 -3
- data/src/Url.cpp +2 -1
- data/src/Url.h +3 -5
- data/src/Visit.cpp +3 -2
- data/src/Visit.h +3 -5
- data/src/WebPage.cpp +129 -44
- data/src/WebPage.h +37 -11
- data/src/WebPageManager.cpp +127 -0
- data/src/WebPageManager.h +59 -0
- data/src/WindowFocus.cpp +32 -0
- data/src/WindowFocus.h +15 -0
- data/src/body.cpp +2 -1
- data/src/capybara.js +38 -10
- data/src/find_command.h +17 -2
- data/src/main.cpp +0 -2
- data/src/webkit_server.pro +36 -0
- data/templates/Command.cpp +2 -4
- data/templates/Command.h +3 -3
- metadata +106 -27
- data/ChangeLog +0 -70
- data/lib/capybara/driver/webkit.rb +0 -136
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'capybara/driver
|
2
|
+
require 'capybara/webkit/driver'
|
3
3
|
|
4
|
-
describe Capybara::Driver
|
4
|
+
describe Capybara::Webkit::Driver do
|
5
5
|
before do
|
6
|
-
@driver = Capybara::Driver
|
6
|
+
@driver = Capybara::Webkit::Driver.new(TestApp, :browser => $webkit_browser)
|
7
7
|
end
|
8
8
|
|
9
9
|
it_should_behave_like "driver"
|
@@ -12,6 +12,7 @@ describe Capybara::Driver::Webkit do
|
|
12
12
|
it_should_behave_like "driver with header support"
|
13
13
|
it_should_behave_like "driver with status code support"
|
14
14
|
it_should_behave_like "driver with frame support"
|
15
|
+
it_should_behave_like "driver with support for window switching"
|
15
16
|
|
16
17
|
it "returns the rack server port" do
|
17
18
|
@driver.server_port.should eq(@driver.instance_variable_get(:@rack_server).port)
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Capybara::Webkit, 'compatibility with selenium' do
|
4
|
+
include AppRunner
|
5
|
+
|
6
|
+
it 'generates the same events as selenium when filling out forms' do
|
7
|
+
run_application_for_html(<<-HTML)
|
8
|
+
<html><body>
|
9
|
+
<form onsubmit="return false">
|
10
|
+
<label for="one">One</label><input type="text" name="one" id="one" />
|
11
|
+
<label for="two">Two</label><input type="text" name="two" id="two" />
|
12
|
+
<input type="submit" value="Submit" id="submit" />
|
13
|
+
</form>
|
14
|
+
<script type="text/javascript">
|
15
|
+
window.log = [];
|
16
|
+
var recordEvent = function (event) {
|
17
|
+
log.push(event.target.id + '.' + event.type);
|
18
|
+
};
|
19
|
+
var elements = document.getElementsByTagName("input");
|
20
|
+
var events = ["mousedown", "mouseup", "click", "keyup", "keydown",
|
21
|
+
"keypress", "focus", "blur"];
|
22
|
+
for (var i = 0; i < elements.length; i++) {
|
23
|
+
for (var j = 0; j < events.length; j++) {
|
24
|
+
elements[i].addEventListener(events[j], recordEvent);
|
25
|
+
}
|
26
|
+
}
|
27
|
+
</script>
|
28
|
+
</body></html>
|
29
|
+
HTML
|
30
|
+
|
31
|
+
compare_events_for_drivers(:reusable_webkit, :selenium) do
|
32
|
+
visit "/"
|
33
|
+
fill_in "One", :with => "some value"
|
34
|
+
fill_in "One", :with => "a new value"
|
35
|
+
fill_in "Two", :with => "other value"
|
36
|
+
click_button "Submit"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def compare_events_for_drivers(first, second, &block)
|
41
|
+
events_for_driver(first, &block).should == events_for_driver(second, &block)
|
42
|
+
end
|
43
|
+
|
44
|
+
def events_for_driver(name, &block)
|
45
|
+
session = Capybara::Session.new(name, AppRunner.app)
|
46
|
+
session.instance_eval(&block)
|
47
|
+
session.evaluate_script("window.log")
|
48
|
+
end
|
49
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'rspec'
|
2
2
|
require 'rspec/autorun'
|
3
3
|
require 'rbconfig'
|
4
|
+
require 'capybara'
|
4
5
|
|
5
6
|
PROJECT_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..')).freeze
|
6
7
|
|
@@ -20,15 +21,22 @@ RSpec.configure do |c|
|
|
20
21
|
c.filter_run_excluding :skip_on_windows => !(RbConfig::CONFIG['host_os'] =~ /mingw32/).nil?
|
21
22
|
end
|
22
23
|
|
23
|
-
require
|
24
|
+
require 'capybara/webkit'
|
25
|
+
connection = Capybara::Webkit::Connection.new(:socket_class => TCPSocket, :stdout => nil)
|
26
|
+
$webkit_browser = Capybara::Webkit::Browser.new(connection)
|
27
|
+
|
28
|
+
if ENV['DEBUG']
|
29
|
+
$webkit_browser.enable_logging
|
30
|
+
end
|
24
31
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
32
|
+
RSpec.configure do |config|
|
33
|
+
config.before { $webkit_browser.reset! }
|
34
|
+
end
|
35
|
+
|
36
|
+
require File.join(spec_dir, "spec_helper")
|
29
37
|
|
30
38
|
Capybara.register_driver :reusable_webkit do |app|
|
31
|
-
Capybara::Driver
|
39
|
+
Capybara::Webkit::Driver.new(app, :browser => $webkit_browser)
|
32
40
|
end
|
33
41
|
|
34
42
|
def with_env_vars(vars)
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# Boots a single Capybara::Server for a Rack application that delegates to another, singleton Rack
|
2
|
+
# application that can be configured for each spec. Also configures Capybara to use that server.
|
3
|
+
|
4
|
+
require 'sinatra/base'
|
5
|
+
|
6
|
+
module AppRunner
|
7
|
+
class << self
|
8
|
+
attr_accessor :app, :app_host
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.boot
|
12
|
+
app_container = lambda { |env| AppRunner.app.call(env) }
|
13
|
+
server = Capybara::Server.new(app_container)
|
14
|
+
server.boot
|
15
|
+
self.app_host = "http://127.0.0.1:#{server.port}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.reset
|
19
|
+
self.app = lambda do |env|
|
20
|
+
[200, { 'Content-Type' => 'html', 'Content-Length' => 0 }, []]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def run_application(app)
|
25
|
+
AppRunner.app = app
|
26
|
+
end
|
27
|
+
|
28
|
+
def driver_for_app(&body)
|
29
|
+
app = Class.new(ExampleApp, &body)
|
30
|
+
run_application app
|
31
|
+
build_driver
|
32
|
+
end
|
33
|
+
|
34
|
+
def driver_for_html(html)
|
35
|
+
run_application_for_html html
|
36
|
+
build_driver
|
37
|
+
end
|
38
|
+
|
39
|
+
def run_application_for_html(html)
|
40
|
+
run_application lambda { |env|
|
41
|
+
[200, { 'Content-Type' => 'text/html', 'Content-Length' => html.size.to_s }, [html]]
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def build_driver
|
48
|
+
Capybara::Webkit::Driver.new(AppRunner.app, :browser => $webkit_browser)
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.included(example_group)
|
52
|
+
example_group.class_eval do
|
53
|
+
before { AppRunner.reset }
|
54
|
+
|
55
|
+
around do |example|
|
56
|
+
Capybara.run_server = false
|
57
|
+
Capybara.app_host = AppRunner.app_host
|
58
|
+
begin
|
59
|
+
example.run
|
60
|
+
ensure
|
61
|
+
Capybara.run_server = true
|
62
|
+
Capybara.app_host = nil
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
class ExampleApp < Sinatra::Base
|
70
|
+
# Sinatra fixes invalid responses that would break QWebPage, so this middleware breaks them again
|
71
|
+
# for testing purposes.
|
72
|
+
class ResponseInvalidator
|
73
|
+
def initialize(app)
|
74
|
+
@app = app
|
75
|
+
end
|
76
|
+
|
77
|
+
def call(env)
|
78
|
+
response = @app.call(env)
|
79
|
+
if response.to_a[1]['X-Response-Invalid']
|
80
|
+
[404, {}, []]
|
81
|
+
else
|
82
|
+
response
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
use ResponseInvalidator
|
88
|
+
|
89
|
+
def invalid_response
|
90
|
+
[200, { 'X-Response-Invalid' => 'TRUE' }, []]
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
AppRunner.boot
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#include "Authenticate.h"
|
2
|
+
#include "WebPage.h"
|
3
|
+
#include "NetworkAccessManager.h"
|
4
|
+
|
5
|
+
Authenticate::Authenticate(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
|
6
|
+
}
|
7
|
+
|
8
|
+
void Authenticate::start() {
|
9
|
+
QString username = arguments()[0];
|
10
|
+
QString password = arguments()[1];
|
11
|
+
|
12
|
+
NetworkAccessManager* networkAccessManager = qobject_cast<NetworkAccessManager*>(page()->networkAccessManager());
|
13
|
+
networkAccessManager->setUserName(username);
|
14
|
+
networkAccessManager->setPassword(password);
|
15
|
+
|
16
|
+
emit finished(new Response(true));
|
17
|
+
}
|
18
|
+
|
data/src/Authenticate.h
ADDED
data/src/Body.h
CHANGED
@@ -1,12 +1,10 @@
|
|
1
|
-
#include "
|
1
|
+
#include "SocketCommand.h"
|
2
2
|
|
3
|
-
class
|
4
|
-
|
5
|
-
class Body : public Command {
|
3
|
+
class Body : public SocketCommand {
|
6
4
|
Q_OBJECT
|
7
5
|
|
8
6
|
public:
|
9
|
-
Body(
|
7
|
+
Body(WebPageManager *, QStringList &arguments, QObject *parent = 0);
|
10
8
|
virtual void start();
|
11
9
|
};
|
12
10
|
|
data/src/ClearCookies.cpp
CHANGED
@@ -1,15 +1,13 @@
|
|
1
1
|
#include "ClearCookies.h"
|
2
2
|
#include "WebPage.h"
|
3
|
+
#include "WebPageManager.h"
|
3
4
|
#include "NetworkCookieJar.h"
|
4
5
|
#include <QNetworkCookie>
|
5
6
|
|
6
|
-
ClearCookies::ClearCookies(
|
7
|
+
ClearCookies::ClearCookies(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {}
|
7
8
|
|
8
9
|
void ClearCookies::start()
|
9
10
|
{
|
10
|
-
|
11
|
-
->networkAccessManager()
|
12
|
-
->cookieJar());
|
13
|
-
jar->clearCookies();
|
11
|
+
manager()->cookieJar()->clearCookies();
|
14
12
|
emit finished(new Response(true));
|
15
13
|
}
|
data/src/ClearCookies.h
CHANGED
@@ -1,11 +1,9 @@
|
|
1
|
-
#include "
|
1
|
+
#include "SocketCommand.h"
|
2
2
|
|
3
|
-
class
|
4
|
-
|
5
|
-
class ClearCookies : public Command {
|
3
|
+
class ClearCookies : public SocketCommand {
|
6
4
|
Q_OBJECT;
|
7
5
|
|
8
6
|
public:
|
9
|
-
ClearCookies(
|
7
|
+
ClearCookies(WebPageManager *, QStringList &arguments, QObject *parent = 0);
|
10
8
|
virtual void start();
|
11
9
|
};
|
@@ -0,0 +1,11 @@
|
|
1
|
+
#include "ClearPromptText.h"
|
2
|
+
#include "WebPage.h"
|
3
|
+
#include "WebPageManager.h"
|
4
|
+
|
5
|
+
ClearPromptText::ClearPromptText(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {}
|
6
|
+
|
7
|
+
void ClearPromptText::start()
|
8
|
+
{
|
9
|
+
page()->setPromptText(QString());
|
10
|
+
emit finished(new Response(true));
|
11
|
+
}
|
data/src/Command.cpp
CHANGED
@@ -1,19 +1,8 @@
|
|
1
|
-
#include "
|
2
|
-
#include "WebPage.h"
|
1
|
+
#include "SocketCommand.h"
|
3
2
|
|
4
|
-
Command::Command(
|
5
|
-
m_page = page;
|
6
|
-
m_arguments = arguments;
|
3
|
+
Command::Command(QObject *parent) : QObject(parent) {
|
7
4
|
}
|
8
5
|
|
9
|
-
|
6
|
+
QString Command::toString() const {
|
7
|
+
return metaObject()->className();
|
10
8
|
}
|
11
|
-
|
12
|
-
WebPage *Command::page() {
|
13
|
-
return m_page;
|
14
|
-
}
|
15
|
-
|
16
|
-
QStringList &Command::arguments() {
|
17
|
-
return m_arguments;
|
18
|
-
}
|
19
|
-
|
data/src/Command.h
CHANGED
@@ -2,29 +2,18 @@
|
|
2
2
|
#define COMMAND_H
|
3
3
|
|
4
4
|
#include <QObject>
|
5
|
-
#include <QStringList>
|
6
5
|
#include "Response.h"
|
7
6
|
|
8
|
-
class WebPage;
|
9
|
-
|
10
7
|
class Command : public QObject {
|
11
8
|
Q_OBJECT
|
12
9
|
|
13
10
|
public:
|
14
|
-
Command(
|
15
|
-
virtual void start();
|
11
|
+
Command(QObject *parent = 0);
|
12
|
+
virtual void start() = 0;
|
13
|
+
virtual QString toString() const;
|
16
14
|
|
17
15
|
signals:
|
18
16
|
void finished(Response *response);
|
19
|
-
|
20
|
-
protected:
|
21
|
-
WebPage *page();
|
22
|
-
QStringList &arguments();
|
23
|
-
|
24
|
-
private:
|
25
|
-
WebPage *m_page;
|
26
|
-
QStringList m_arguments;
|
27
|
-
|
28
17
|
};
|
29
18
|
|
30
19
|
#endif
|
data/src/CommandFactory.cpp
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
#include "CommandFactory.h"
|
2
2
|
#include "NullCommand.h"
|
3
|
+
#include "SocketCommand.h"
|
3
4
|
#include "Visit.h"
|
4
5
|
#include "Find.h"
|
5
|
-
#include "Command.h"
|
6
6
|
#include "Reset.h"
|
7
7
|
#include "Node.h"
|
8
8
|
#include "Url.h"
|
@@ -22,16 +22,30 @@
|
|
22
22
|
#include "ConsoleMessages.h"
|
23
23
|
#include "RequestedUrl.h"
|
24
24
|
#include "CurrentUrl.h"
|
25
|
+
#include "SetTimeout.h"
|
26
|
+
#include "GetTimeout.h"
|
25
27
|
#include "ResizeWindow.h"
|
26
28
|
#include "IgnoreSslErrors.h"
|
29
|
+
#include "SetSkipImageLoading.h"
|
30
|
+
#include "WindowFocus.h"
|
31
|
+
#include "GetWindowHandles.h"
|
32
|
+
#include "GetWindowHandle.h"
|
33
|
+
#include "WebPageManager.h"
|
34
|
+
#include "Authenticate.h"
|
35
|
+
#include "EnableLogging.h"
|
36
|
+
#include "SetConfirmAction.h"
|
37
|
+
#include "SetPromptAction.h"
|
38
|
+
#include "SetPromptText.h"
|
39
|
+
#include "ClearPromptText.h"
|
40
|
+
#include "JavascriptAlertMessages.h"
|
41
|
+
#include "JavascriptConfirmMessages.h"
|
42
|
+
#include "JavascriptPromptMessages.h"
|
27
43
|
|
28
|
-
CommandFactory::CommandFactory(
|
29
|
-
|
44
|
+
CommandFactory::CommandFactory(WebPageManager *manager, QObject *parent) : QObject(parent) {
|
45
|
+
m_manager = manager;
|
30
46
|
}
|
31
47
|
|
32
48
|
Command *CommandFactory::createCommand(const char *name, QStringList &arguments) {
|
33
49
|
#include "find_command.h"
|
34
|
-
|
35
|
-
arguments.append(QString(name));
|
36
|
-
return new NullCommand(m_page, arguments);
|
50
|
+
return new NullCommand(QString(name));
|
37
51
|
}
|
data/src/CommandFactory.h
CHANGED
@@ -2,15 +2,16 @@
|
|
2
2
|
|
3
3
|
class Command;
|
4
4
|
class WebPage;
|
5
|
+
class WebPageManager;
|
5
6
|
|
6
7
|
class CommandFactory : public QObject {
|
7
8
|
Q_OBJECT
|
8
9
|
|
9
10
|
public:
|
10
|
-
CommandFactory(
|
11
|
+
CommandFactory(WebPageManager *, QObject *parent = 0);
|
11
12
|
Command *createCommand(const char *name, QStringList &arguments);
|
12
13
|
|
13
14
|
private:
|
14
|
-
|
15
|
+
WebPageManager *m_manager;
|
15
16
|
};
|
16
17
|
|
data/src/CommandParser.cpp
CHANGED
data/src/Connection.cpp
CHANGED
@@ -1,58 +1,54 @@
|
|
1
1
|
#include "Connection.h"
|
2
2
|
#include "WebPage.h"
|
3
|
+
#include "WebPageManager.h"
|
3
4
|
#include "CommandParser.h"
|
4
5
|
#include "CommandFactory.h"
|
5
6
|
#include "PageLoadingCommand.h"
|
6
|
-
#include "
|
7
|
+
#include "TimeoutCommand.h"
|
8
|
+
#include "SocketCommand.h"
|
7
9
|
|
8
10
|
#include <QTcpSocket>
|
9
11
|
|
10
|
-
Connection::Connection(QTcpSocket *socket,
|
12
|
+
Connection::Connection(QTcpSocket *socket, WebPageManager *manager, QObject *parent) :
|
11
13
|
QObject(parent) {
|
12
14
|
m_socket = socket;
|
13
|
-
|
14
|
-
m_commandFactory = new CommandFactory(
|
15
|
+
m_manager = manager;
|
16
|
+
m_commandFactory = new CommandFactory(m_manager, this);
|
15
17
|
m_commandParser = new CommandParser(socket, m_commandFactory, this);
|
16
18
|
m_pageSuccess = true;
|
17
|
-
m_commandWaiting = false;
|
18
19
|
connect(m_socket, SIGNAL(readyRead()), m_commandParser, SLOT(checkNext()));
|
19
20
|
connect(m_commandParser, SIGNAL(commandReady(Command *)), this, SLOT(commandReady(Command *)));
|
20
|
-
connect(
|
21
|
+
connect(m_manager, SIGNAL(pageFinished(bool)), this, SLOT(pendingLoadFinished(bool)));
|
21
22
|
}
|
22
23
|
|
23
24
|
void Connection::commandReady(Command *command) {
|
24
|
-
|
25
|
-
|
26
|
-
m_commandWaiting = true;
|
27
|
-
else
|
28
|
-
startCommand();
|
25
|
+
m_manager->logger() << "Received" << command->toString();
|
26
|
+
startCommand(command);
|
29
27
|
}
|
30
28
|
|
31
|
-
void Connection::startCommand() {
|
32
|
-
m_commandWaiting = false;
|
29
|
+
void Connection::startCommand(Command *command) {
|
33
30
|
if (m_pageSuccess) {
|
34
|
-
|
35
|
-
connect(
|
36
|
-
|
31
|
+
command = new TimeoutCommand(new PageLoadingCommand(command, m_manager, this), m_manager, this);
|
32
|
+
connect(command, SIGNAL(finished(Response *)), this, SLOT(finishCommand(Response *)));
|
33
|
+
command->start();
|
37
34
|
} else {
|
38
35
|
writePageLoadFailure();
|
39
36
|
}
|
40
37
|
}
|
41
38
|
|
42
39
|
void Connection::pendingLoadFinished(bool success) {
|
43
|
-
m_pageSuccess = success;
|
44
|
-
if (m_commandWaiting)
|
45
|
-
startCommand();
|
40
|
+
m_pageSuccess = m_pageSuccess && success;
|
46
41
|
}
|
47
42
|
|
48
43
|
void Connection::writePageLoadFailure() {
|
49
44
|
m_pageSuccess = true;
|
50
|
-
QString message =
|
45
|
+
QString message = currentPage()->failureString();
|
51
46
|
writeResponse(new Response(false, message));
|
52
47
|
}
|
53
48
|
|
54
49
|
void Connection::finishCommand(Response *response) {
|
55
|
-
|
50
|
+
m_pageSuccess = true;
|
51
|
+
sender()->deleteLater();
|
56
52
|
writeResponse(response);
|
57
53
|
}
|
58
54
|
|
@@ -62,6 +58,8 @@ void Connection::writeResponse(Response *response) {
|
|
62
58
|
else
|
63
59
|
m_socket->write("failure\n");
|
64
60
|
|
61
|
+
m_manager->logger() << "Wrote response" << response->isSuccess() << response->message();
|
62
|
+
|
65
63
|
QByteArray messageUtf8 = response->message();
|
66
64
|
QString messageLength = QString::number(messageUtf8.size()) + "\n";
|
67
65
|
m_socket->write(messageLength.toAscii());
|
@@ -69,3 +67,6 @@ void Connection::writeResponse(Response *response) {
|
|
69
67
|
delete response;
|
70
68
|
}
|
71
69
|
|
70
|
+
WebPage *Connection::currentPage() {
|
71
|
+
return m_manager->currentPage();
|
72
|
+
}
|