capybara-webkit 0.12.1 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. data/.gitignore +2 -1
  2. data/GOALS +9 -0
  3. data/Gemfile.lock +15 -12
  4. data/LICENSE +1 -1
  5. data/NEWS.md +18 -0
  6. data/README.md +81 -2
  7. data/capybara-webkit.gemspec +1 -1
  8. data/lib/capybara/webkit.rb +11 -6
  9. data/lib/capybara/{driver/webkit → webkit}/browser.rb +90 -4
  10. data/lib/capybara/{driver/webkit → webkit}/connection.rb +48 -47
  11. data/lib/capybara/{driver/webkit → webkit}/cookie_jar.rb +1 -1
  12. data/lib/capybara/webkit/driver.rb +186 -0
  13. data/lib/capybara/webkit/errors.rb +10 -0
  14. data/lib/capybara/{driver/webkit → webkit}/node.rb +12 -4
  15. data/lib/capybara/{driver/webkit → webkit}/socket_debugger.rb +4 -1
  16. data/lib/capybara/{driver/webkit → webkit}/version.rb +1 -1
  17. data/lib/capybara_webkit_builder.rb +17 -3
  18. data/spec/browser_spec.rb +95 -7
  19. data/spec/connection_spec.rb +16 -5
  20. data/spec/cookie_jar_spec.rb +3 -3
  21. data/spec/driver_rendering_spec.rb +19 -26
  22. data/spec/driver_resize_window_spec.rb +3 -3
  23. data/spec/driver_spec.rb +1200 -822
  24. data/spec/integration/driver_spec.rb +4 -3
  25. data/spec/selenium_compatibility_spec.rb +49 -0
  26. data/spec/spec_helper.rb +14 -6
  27. data/spec/support/app_runner.rb +94 -0
  28. data/src/Authenticate.cpp +18 -0
  29. data/src/Authenticate.h +12 -0
  30. data/src/Body.h +3 -5
  31. data/src/ClearCookies.cpp +3 -5
  32. data/src/ClearCookies.h +3 -5
  33. data/src/ClearPromptText.cpp +11 -0
  34. data/src/ClearPromptText.h +9 -0
  35. data/src/Command.cpp +4 -15
  36. data/src/Command.h +3 -14
  37. data/src/CommandFactory.cpp +20 -6
  38. data/src/CommandFactory.h +3 -2
  39. data/src/CommandParser.cpp +1 -1
  40. data/src/Connection.cpp +22 -21
  41. data/src/Connection.h +5 -6
  42. data/src/ConsoleMessages.cpp +2 -1
  43. data/src/ConsoleMessages.h +3 -5
  44. data/src/CurrentUrl.cpp +9 -48
  45. data/src/CurrentUrl.h +8 -8
  46. data/src/EnableLogging.cpp +10 -0
  47. data/src/EnableLogging.h +12 -0
  48. data/src/Evaluate.cpp +2 -1
  49. data/src/Evaluate.h +3 -5
  50. data/src/Execute.cpp +2 -1
  51. data/src/Execute.h +3 -5
  52. data/src/Find.cpp +3 -2
  53. data/src/Find.h +3 -5
  54. data/src/FrameFocus.cpp +3 -2
  55. data/src/FrameFocus.h +3 -4
  56. data/src/GetCookies.cpp +3 -4
  57. data/src/GetCookies.h +3 -5
  58. data/src/GetTimeout.cpp +9 -0
  59. data/src/GetTimeout.h +11 -0
  60. data/src/GetWindowHandle.cpp +11 -0
  61. data/src/GetWindowHandle.h +10 -0
  62. data/src/GetWindowHandles.cpp +20 -0
  63. data/src/GetWindowHandles.h +10 -0
  64. data/src/Header.cpp +2 -1
  65. data/src/Header.h +3 -5
  66. data/src/Headers.cpp +8 -2
  67. data/src/Headers.h +3 -5
  68. data/src/IgnoreSslErrors.cpp +4 -3
  69. data/src/IgnoreSslErrors.h +3 -5
  70. data/src/JavascriptAlertMessages.cpp +10 -0
  71. data/src/JavascriptAlertMessages.h +9 -0
  72. data/src/JavascriptConfirmMessages.cpp +10 -0
  73. data/src/JavascriptConfirmMessages.h +9 -0
  74. data/src/JavascriptInvocation.cpp +1 -1
  75. data/src/JavascriptInvocation.h +1 -1
  76. data/src/JavascriptPromptMessages.cpp +10 -0
  77. data/src/JavascriptPromptMessages.h +9 -0
  78. data/src/NetworkAccessManager.cpp +38 -5
  79. data/src/NetworkAccessManager.h +20 -0
  80. data/src/Node.cpp +6 -1
  81. data/src/Node.h +4 -5
  82. data/src/NullCommand.cpp +5 -2
  83. data/src/NullCommand.h +4 -3
  84. data/src/PageLoadingCommand.cpp +12 -7
  85. data/src/PageLoadingCommand.h +6 -9
  86. data/src/Render.cpp +2 -1
  87. data/src/Render.h +3 -5
  88. data/src/RequestedUrl.cpp +2 -1
  89. data/src/RequestedUrl.h +3 -5
  90. data/src/Reset.cpp +3 -17
  91. data/src/Reset.h +3 -8
  92. data/src/ResizeWindow.cpp +2 -1
  93. data/src/ResizeWindow.h +3 -5
  94. data/src/Response.cpp +4 -0
  95. data/src/Response.h +1 -0
  96. data/src/Server.cpp +2 -3
  97. data/src/Server.h +0 -2
  98. data/src/SetConfirmAction.cpp +11 -0
  99. data/src/SetConfirmAction.h +9 -0
  100. data/src/SetCookie.cpp +3 -4
  101. data/src/SetCookie.h +3 -5
  102. data/src/SetPromptAction.cpp +11 -0
  103. data/src/SetPromptAction.h +9 -0
  104. data/src/SetPromptText.cpp +11 -0
  105. data/src/SetPromptText.h +9 -0
  106. data/src/SetProxy.cpp +2 -1
  107. data/src/SetProxy.h +3 -5
  108. data/src/SetSkipImageLoading.cpp +12 -0
  109. data/src/SetSkipImageLoading.h +9 -0
  110. data/src/SetTimeout.cpp +19 -0
  111. data/src/SetTimeout.h +9 -0
  112. data/src/SocketCommand.cpp +21 -0
  113. data/src/SocketCommand.h +29 -0
  114. data/src/Source.cpp +3 -2
  115. data/src/Source.h +3 -4
  116. data/src/Status.cpp +2 -1
  117. data/src/Status.h +3 -5
  118. data/src/TimeoutCommand.cpp +69 -0
  119. data/src/TimeoutCommand.h +41 -0
  120. data/src/UnsupportedContentHandler.cpp +11 -17
  121. data/src/UnsupportedContentHandler.h +5 -3
  122. data/src/Url.cpp +2 -1
  123. data/src/Url.h +3 -5
  124. data/src/Visit.cpp +3 -2
  125. data/src/Visit.h +3 -5
  126. data/src/WebPage.cpp +129 -44
  127. data/src/WebPage.h +37 -11
  128. data/src/WebPageManager.cpp +127 -0
  129. data/src/WebPageManager.h +59 -0
  130. data/src/WindowFocus.cpp +32 -0
  131. data/src/WindowFocus.h +15 -0
  132. data/src/body.cpp +2 -1
  133. data/src/capybara.js +38 -10
  134. data/src/find_command.h +17 -2
  135. data/src/main.cpp +0 -2
  136. data/src/webkit_server.pro +36 -0
  137. data/templates/Command.cpp +2 -4
  138. data/templates/Command.h +3 -3
  139. metadata +106 -27
  140. data/ChangeLog +0 -70
  141. data/lib/capybara/driver/webkit.rb +0 -136
@@ -1,9 +1,9 @@
1
1
  require 'spec_helper'
2
- require 'capybara/driver/webkit'
2
+ require 'capybara/webkit/driver'
3
3
 
4
- describe Capybara::Driver::Webkit do
4
+ describe Capybara::Webkit::Driver do
5
5
  before do
6
- @driver = Capybara::Driver::Webkit.new(TestApp, :browser => $webkit_browser)
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
@@ -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 File.join(spec_dir, "spec_helper")
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
- require 'capybara/driver/webkit/connection'
26
- require 'capybara/driver/webkit/browser'
27
- connection = Capybara::Driver::Webkit::Connection.new(:socket_class => TCPSocket, :stdout => nil)
28
- $webkit_browser = Capybara::Driver::Webkit::Browser.new(connection)
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::Webkit.new(app, :browser => $webkit_browser)
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
+
@@ -0,0 +1,12 @@
1
+ #include "SocketCommand.h"
2
+
3
+ class WebPage;
4
+
5
+ class Authenticate : public SocketCommand {
6
+ Q_OBJECT
7
+
8
+ public:
9
+ Authenticate(WebPageManager *manager, QStringList &arguments, QObject *parent = 0);
10
+ virtual void start();
11
+ };
12
+
data/src/Body.h CHANGED
@@ -1,12 +1,10 @@
1
- #include "Command.h"
1
+ #include "SocketCommand.h"
2
2
 
3
- class WebPage;
4
-
5
- class Body : public Command {
3
+ class Body : public SocketCommand {
6
4
  Q_OBJECT
7
5
 
8
6
  public:
9
- Body(WebPage *page, QStringList &arguments, QObject *parent = 0);
7
+ Body(WebPageManager *, QStringList &arguments, QObject *parent = 0);
10
8
  virtual void start();
11
9
  };
12
10
 
@@ -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(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {}
7
+ ClearCookies::ClearCookies(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {}
7
8
 
8
9
  void ClearCookies::start()
9
10
  {
10
- NetworkCookieJar *jar = qobject_cast<NetworkCookieJar*>(page()
11
- ->networkAccessManager()
12
- ->cookieJar());
13
- jar->clearCookies();
11
+ manager()->cookieJar()->clearCookies();
14
12
  emit finished(new Response(true));
15
13
  }
@@ -1,11 +1,9 @@
1
- #include "Command.h"
1
+ #include "SocketCommand.h"
2
2
 
3
- class WebPage;
4
-
5
- class ClearCookies : public Command {
3
+ class ClearCookies : public SocketCommand {
6
4
  Q_OBJECT;
7
5
 
8
6
  public:
9
- ClearCookies(WebPage *page, QStringList &arguments, QObject *parent = 0);
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
+ }
@@ -0,0 +1,9 @@
1
+ #include "SocketCommand.h"
2
+
3
+ class ClearPromptText : public SocketCommand {
4
+ Q_OBJECT;
5
+
6
+ public:
7
+ ClearPromptText(WebPageManager *manager, QStringList &arguments, QObject *parent = 0);
8
+ virtual void start();
9
+ };
@@ -1,19 +1,8 @@
1
- #include "Command.h"
2
- #include "WebPage.h"
1
+ #include "SocketCommand.h"
3
2
 
4
- Command::Command(WebPage *page, QStringList &arguments, QObject *parent) : QObject(parent) {
5
- m_page = page;
6
- m_arguments = arguments;
3
+ Command::Command(QObject *parent) : QObject(parent) {
7
4
  }
8
5
 
9
- void Command::start() {
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
-
@@ -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(WebPage *page, QStringList &arguments, QObject *parent = 0);
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
@@ -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(WebPage *page, QObject *parent) : QObject(parent) {
29
- m_page = page;
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
- arguments.clear();
35
- arguments.append(QString(name));
36
- return new NullCommand(m_page, arguments);
50
+ return new NullCommand(QString(name));
37
51
  }
@@ -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(WebPage *page, QObject *parent = 0);
11
+ CommandFactory(WebPageManager *, QObject *parent = 0);
11
12
  Command *createCommand(const char *name, QStringList &arguments);
12
13
 
13
14
  private:
14
- WebPage *m_page;
15
+ WebPageManager *m_manager;
15
16
  };
16
17
 
@@ -1,6 +1,6 @@
1
1
  #include "CommandParser.h"
2
2
  #include "CommandFactory.h"
3
- #include "Command.h"
3
+ #include "SocketCommand.h"
4
4
 
5
5
  #include <QIODevice>
6
6
 
@@ -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 "Command.h"
7
+ #include "TimeoutCommand.h"
8
+ #include "SocketCommand.h"
7
9
 
8
10
  #include <QTcpSocket>
9
11
 
10
- Connection::Connection(QTcpSocket *socket, WebPage *page, QObject *parent) :
12
+ Connection::Connection(QTcpSocket *socket, WebPageManager *manager, QObject *parent) :
11
13
  QObject(parent) {
12
14
  m_socket = socket;
13
- m_page = page;
14
- m_commandFactory = new CommandFactory(page, this);
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(m_page, SIGNAL(pageFinished(bool)), this, SLOT(pendingLoadFinished(bool)));
21
+ connect(m_manager, SIGNAL(pageFinished(bool)), this, SLOT(pendingLoadFinished(bool)));
21
22
  }
22
23
 
23
24
  void Connection::commandReady(Command *command) {
24
- m_queuedCommand = command;
25
- if (m_page->isLoading())
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
- m_runningCommand = new PageLoadingCommand(m_queuedCommand, m_page, this);
35
- connect(m_runningCommand, SIGNAL(finished(Response *)), this, SLOT(finishCommand(Response *)));
36
- m_runningCommand->start();
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 = m_page->failureString();
45
+ QString message = currentPage()->failureString();
51
46
  writeResponse(new Response(false, message));
52
47
  }
53
48
 
54
49
  void Connection::finishCommand(Response *response) {
55
- m_runningCommand->deleteLater();
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
+ }