capybara-webkit 0.11.0 → 0.12.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 (86) hide show
  1. data/.gitignore +3 -1
  2. data/Gemfile.lock +5 -4
  3. data/NEWS.md +11 -0
  4. data/README.md +42 -0
  5. data/lib/capybara/driver/webkit.rb +7 -2
  6. data/lib/capybara/driver/webkit/browser.rb +22 -96
  7. data/lib/capybara/driver/webkit/connection.rb +120 -0
  8. data/lib/capybara/driver/webkit/version.rb +1 -1
  9. data/lib/capybara/webkit/matchers.rb +2 -4
  10. data/lib/capybara_webkit_builder.rb +22 -4
  11. data/spec/browser_spec.rb +19 -29
  12. data/spec/connection_spec.rb +54 -0
  13. data/spec/driver_resize_window_spec.rb +59 -0
  14. data/spec/driver_spec.rb +175 -27
  15. data/spec/spec_helper.rb +9 -2
  16. data/src/Body.h +2 -2
  17. data/src/ClearCookies.cpp +2 -5
  18. data/src/ClearCookies.h +2 -2
  19. data/src/Command.cpp +7 -3
  20. data/src/Command.h +4 -2
  21. data/src/CommandFactory.cpp +7 -2
  22. data/src/CommandFactory.h +1 -1
  23. data/src/CommandParser.cpp +13 -5
  24. data/src/CommandParser.h +6 -2
  25. data/src/Connection.cpp +18 -47
  26. data/src/Connection.h +5 -7
  27. data/src/ConsoleMessages.cpp +2 -3
  28. data/src/ConsoleMessages.h +2 -2
  29. data/src/CurrentUrl.cpp +3 -6
  30. data/src/CurrentUrl.h +2 -2
  31. data/src/Evaluate.cpp +3 -3
  32. data/src/Evaluate.h +2 -2
  33. data/src/Execute.cpp +4 -4
  34. data/src/Execute.h +2 -2
  35. data/src/Find.cpp +4 -4
  36. data/src/Find.h +2 -2
  37. data/src/FrameFocus.cpp +7 -7
  38. data/src/FrameFocus.h +2 -2
  39. data/src/GetCookies.cpp +2 -4
  40. data/src/GetCookies.h +2 -2
  41. data/src/Header.cpp +4 -4
  42. data/src/Header.h +2 -2
  43. data/src/Headers.cpp +2 -3
  44. data/src/Headers.h +2 -2
  45. data/src/IgnoreSslErrors.cpp +12 -0
  46. data/src/IgnoreSslErrors.h +12 -0
  47. data/src/NetworkAccessManager.cpp +4 -0
  48. data/src/NetworkAccessManager.h +2 -1
  49. data/src/Node.cpp +3 -3
  50. data/src/Node.h +2 -2
  51. data/src/NullCommand.cpp +10 -0
  52. data/src/NullCommand.h +11 -0
  53. data/src/PageLoadingCommand.cpp +46 -0
  54. data/src/PageLoadingCommand.h +40 -0
  55. data/src/Render.cpp +5 -6
  56. data/src/Render.h +2 -2
  57. data/src/RequestedUrl.cpp +3 -6
  58. data/src/RequestedUrl.h +2 -2
  59. data/src/Reset.cpp +8 -7
  60. data/src/Reset.h +2 -2
  61. data/src/ResizeWindow.cpp +16 -0
  62. data/src/ResizeWindow.h +12 -0
  63. data/src/Response.cpp +6 -1
  64. data/src/Response.h +4 -2
  65. data/src/Server.cpp +2 -3
  66. data/src/Server.h +1 -1
  67. data/src/SetCookie.cpp +3 -5
  68. data/src/SetCookie.h +2 -2
  69. data/src/SetProxy.cpp +7 -9
  70. data/src/SetProxy.h +2 -2
  71. data/src/Source.cpp +2 -4
  72. data/src/Source.h +2 -2
  73. data/src/Status.cpp +2 -3
  74. data/src/Status.h +2 -2
  75. data/src/Url.cpp +3 -6
  76. data/src/Url.h +2 -2
  77. data/src/Visit.cpp +4 -13
  78. data/src/Visit.h +2 -5
  79. data/src/WebPage.cpp +11 -9
  80. data/src/WebPage.h +3 -3
  81. data/src/body.cpp +2 -3
  82. data/src/capybara.js +58 -3
  83. data/src/find_command.h +3 -1
  84. data/src/main.cpp +1 -2
  85. data/src/webkit_server.pro +8 -0
  86. metadata +29 -16
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'rspec'
2
2
  require 'rspec/autorun'
3
+ require 'rbconfig'
3
4
 
4
5
  PROJECT_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..')).freeze
5
6
 
@@ -15,10 +16,16 @@ $:.detect do |dir|
15
16
  end
16
17
  end
17
18
 
18
- require File.join(spec_dir,"spec_helper")
19
+ RSpec.configure do |c|
20
+ c.filter_run_excluding :skip_on_windows => !(RbConfig::CONFIG['host_os'] =~ /mingw32/).nil?
21
+ end
22
+
23
+ require File.join(spec_dir, "spec_helper")
19
24
 
25
+ require 'capybara/driver/webkit/connection'
20
26
  require 'capybara/driver/webkit/browser'
21
- $webkit_browser = Capybara::Driver::Webkit::Browser.new(:socket_class => TCPSocket, :stdout => nil)
27
+ connection = Capybara::Driver::Webkit::Connection.new(:socket_class => TCPSocket, :stdout => nil)
28
+ $webkit_browser = Capybara::Driver::Webkit::Browser.new(connection)
22
29
 
23
30
  Capybara.register_driver :reusable_webkit do |app|
24
31
  Capybara::Driver::Webkit.new(app, :browser => $webkit_browser)
data/src/Body.h CHANGED
@@ -6,7 +6,7 @@ class Body : public Command {
6
6
  Q_OBJECT
7
7
 
8
8
  public:
9
- Body(WebPage *page, QObject *parent = 0);
10
- virtual void start(QStringList &arguments);
9
+ Body(WebPage *page, QStringList &arguments, QObject *parent = 0);
10
+ virtual void start();
11
11
  };
12
12
 
data/src/ClearCookies.cpp CHANGED
@@ -3,13 +3,10 @@
3
3
  #include "NetworkCookieJar.h"
4
4
  #include <QNetworkCookie>
5
5
 
6
- ClearCookies::ClearCookies(WebPage *page, QObject *parent)
7
- : Command(page, parent)
8
- { }
6
+ ClearCookies::ClearCookies(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {}
9
7
 
10
- void ClearCookies::start(QStringList &arguments)
8
+ void ClearCookies::start()
11
9
  {
12
- Q_UNUSED(arguments);
13
10
  NetworkCookieJar *jar = qobject_cast<NetworkCookieJar*>(page()
14
11
  ->networkAccessManager()
15
12
  ->cookieJar());
data/src/ClearCookies.h CHANGED
@@ -6,6 +6,6 @@ class ClearCookies : public Command {
6
6
  Q_OBJECT;
7
7
 
8
8
  public:
9
- ClearCookies(WebPage *page, QObject *parent = 0);
10
- virtual void start(QStringList &arguments);
9
+ ClearCookies(WebPage *page, QStringList &arguments, QObject *parent = 0);
10
+ virtual void start();
11
11
  };
data/src/Command.cpp CHANGED
@@ -1,15 +1,19 @@
1
1
  #include "Command.h"
2
2
  #include "WebPage.h"
3
3
 
4
- Command::Command(WebPage *page, QObject *parent) : QObject(parent) {
4
+ Command::Command(WebPage *page, QStringList &arguments, QObject *parent) : QObject(parent) {
5
5
  m_page = page;
6
+ m_arguments = arguments;
6
7
  }
7
8
 
8
- void Command::start(QStringList &arguments) {
9
- Q_UNUSED(arguments);
9
+ void Command::start() {
10
10
  }
11
11
 
12
12
  WebPage *Command::page() {
13
13
  return m_page;
14
14
  }
15
15
 
16
+ QStringList &Command::arguments() {
17
+ return m_arguments;
18
+ }
19
+
data/src/Command.h CHANGED
@@ -11,17 +11,19 @@ class Command : public QObject {
11
11
  Q_OBJECT
12
12
 
13
13
  public:
14
- Command(WebPage *page, QObject *parent = 0);
15
- virtual void start(QStringList &arguments);
14
+ Command(WebPage *page, QStringList &arguments, QObject *parent = 0);
15
+ virtual void start();
16
16
 
17
17
  signals:
18
18
  void finished(Response *response);
19
19
 
20
20
  protected:
21
21
  WebPage *page();
22
+ QStringList &arguments();
22
23
 
23
24
  private:
24
25
  WebPage *m_page;
26
+ QStringList m_arguments;
25
27
 
26
28
  };
27
29
 
@@ -1,4 +1,5 @@
1
1
  #include "CommandFactory.h"
2
+ #include "NullCommand.h"
2
3
  #include "Visit.h"
3
4
  #include "Find.h"
4
5
  #include "Command.h"
@@ -21,12 +22,16 @@
21
22
  #include "ConsoleMessages.h"
22
23
  #include "RequestedUrl.h"
23
24
  #include "CurrentUrl.h"
25
+ #include "ResizeWindow.h"
26
+ #include "IgnoreSslErrors.h"
24
27
 
25
28
  CommandFactory::CommandFactory(WebPage *page, QObject *parent) : QObject(parent) {
26
29
  m_page = page;
27
30
  }
28
31
 
29
- Command *CommandFactory::createCommand(const char *name) {
32
+ Command *CommandFactory::createCommand(const char *name, QStringList &arguments) {
30
33
  #include "find_command.h"
31
- return NULL;
34
+ arguments.clear();
35
+ arguments.append(QString(name));
36
+ return new NullCommand(m_page, arguments);
32
37
  }
data/src/CommandFactory.h CHANGED
@@ -8,7 +8,7 @@ class CommandFactory : public QObject {
8
8
 
9
9
  public:
10
10
  CommandFactory(WebPage *page, QObject *parent = 0);
11
- Command *createCommand(const char *name);
11
+ Command *createCommand(const char *name, QStringList &arguments);
12
12
 
13
13
  private:
14
14
  WebPage *m_page;
@@ -1,11 +1,14 @@
1
1
  #include "CommandParser.h"
2
+ #include "CommandFactory.h"
3
+ #include "Command.h"
2
4
 
3
5
  #include <QIODevice>
4
6
 
5
- CommandParser::CommandParser(QIODevice *device, QObject *parent) :
7
+ CommandParser::CommandParser(QIODevice *device, CommandFactory *commandFactory, QObject *parent) :
6
8
  QObject(parent) {
7
9
  m_device = device;
8
10
  m_expectingDataSize = -1;
11
+ m_commandFactory = commandFactory;
9
12
  connect(m_device, SIGNAL(readyRead()), this, SLOT(checkNext()));
10
13
  }
11
14
 
@@ -60,9 +63,14 @@ void CommandParser::processArgument(const char *data) {
60
63
  }
61
64
 
62
65
  if (m_arguments.length() == m_argumentsExpected) {
63
- emit commandReady(m_commandName, m_arguments);
64
- m_commandName = QString();
65
- m_arguments.clear();
66
- m_argumentsExpected = -1;
66
+ Command *command = m_commandFactory->createCommand(m_commandName.toAscii().constData(), m_arguments);
67
+ emit commandReady(command);
68
+ reset();
67
69
  }
68
70
  }
71
+
72
+ void CommandParser::reset() {
73
+ m_commandName = QString();
74
+ m_arguments.clear();
75
+ m_argumentsExpected = -1;
76
+ }
data/src/CommandParser.h CHANGED
@@ -2,28 +2,32 @@
2
2
  #include <QStringList>
3
3
 
4
4
  class QIODevice;
5
+ class CommandFactory;
6
+ class Command;
5
7
 
6
8
  class CommandParser : public QObject {
7
9
  Q_OBJECT
8
10
 
9
11
  public:
10
- CommandParser(QIODevice *device, QObject *parent = 0);
12
+ CommandParser(QIODevice *device, CommandFactory *commandFactory, QObject *parent = 0);
11
13
 
12
14
  public slots:
13
15
  void checkNext();
14
16
 
15
17
  signals:
16
- void commandReady(QString commandName, QStringList arguments);
18
+ void commandReady(Command *command);
17
19
 
18
20
  private:
19
21
  void readLine();
20
22
  void readDataBlock();
21
23
  void processNext(const char *line);
22
24
  void processArgument(const char *data);
25
+ void reset();
23
26
  QIODevice *m_device;
24
27
  QString m_commandName;
25
28
  QStringList m_arguments;
26
29
  int m_argumentsExpected;
27
30
  int m_expectingDataSize;
31
+ CommandFactory *m_commandFactory;
28
32
  };
29
33
 
data/src/Connection.cpp CHANGED
@@ -1,34 +1,27 @@
1
1
  #include "Connection.h"
2
2
  #include "WebPage.h"
3
- #include "UnsupportedContentHandler.h"
4
3
  #include "CommandParser.h"
5
4
  #include "CommandFactory.h"
5
+ #include "PageLoadingCommand.h"
6
6
  #include "Command.h"
7
7
 
8
8
  #include <QTcpSocket>
9
- #include <iostream>
10
9
 
11
10
  Connection::Connection(QTcpSocket *socket, WebPage *page, QObject *parent) :
12
11
  QObject(parent) {
13
12
  m_socket = socket;
14
13
  m_page = page;
15
- m_commandParser = new CommandParser(socket, this);
16
14
  m_commandFactory = new CommandFactory(page, this);
17
- m_command = NULL;
15
+ m_commandParser = new CommandParser(socket, m_commandFactory, this);
18
16
  m_pageSuccess = true;
19
17
  m_commandWaiting = false;
20
- m_pageLoadingFromCommand = false;
21
- m_pendingResponse = NULL;
22
18
  connect(m_socket, SIGNAL(readyRead()), m_commandParser, SLOT(checkNext()));
23
- connect(m_commandParser, SIGNAL(commandReady(QString, QStringList)), this, SLOT(commandReady(QString, QStringList)));
19
+ connect(m_commandParser, SIGNAL(commandReady(Command *)), this, SLOT(commandReady(Command *)));
24
20
  connect(m_page, SIGNAL(pageFinished(bool)), this, SLOT(pendingLoadFinished(bool)));
25
21
  }
26
22
 
27
-
28
- void Connection::commandReady(QString commandName, QStringList arguments) {
29
- m_commandName = commandName;
30
- m_arguments = arguments;
31
-
23
+ void Connection::commandReady(Command *command) {
24
+ m_queuedCommand = command;
32
25
  if (m_page->isLoading())
33
26
  m_commandWaiting = true;
34
27
  else
@@ -38,51 +31,29 @@ void Connection::commandReady(QString commandName, QStringList arguments) {
38
31
  void Connection::startCommand() {
39
32
  m_commandWaiting = false;
40
33
  if (m_pageSuccess) {
41
- m_command = m_commandFactory->createCommand(m_commandName.toAscii().constData());
42
- if (m_command) {
43
- connect(m_page, SIGNAL(loadStarted()), this, SLOT(pageLoadingFromCommand()));
44
- connect(m_command,
45
- SIGNAL(finished(Response *)),
46
- this,
47
- SLOT(finishCommand(Response *)));
48
- m_command->start(m_arguments);
49
- } else {
50
- QString failure = QString("[Capybara WebKit] Unknown command: ") + m_commandName + "\n";
51
- writeResponse(new Response(false, failure));
52
- }
53
- m_commandName = QString();
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();
54
37
  } else {
55
- m_pageSuccess = true;
56
- QString message = m_page->failureString();
57
- writeResponse(new Response(false, message));
38
+ writePageLoadFailure();
58
39
  }
59
40
  }
60
41
 
61
- void Connection::pageLoadingFromCommand() {
62
- m_pageLoadingFromCommand = true;
63
- }
64
-
65
42
  void Connection::pendingLoadFinished(bool success) {
66
43
  m_pageSuccess = success;
67
44
  if (m_commandWaiting)
68
45
  startCommand();
69
- if (m_pageLoadingFromCommand) {
70
- m_pageLoadingFromCommand = false;
71
- if (m_pendingResponse) {
72
- writeResponse(m_pendingResponse);
73
- m_pendingResponse = NULL;
74
- }
75
- }
46
+ }
47
+
48
+ void Connection::writePageLoadFailure() {
49
+ m_pageSuccess = true;
50
+ QString message = m_page->failureString();
51
+ writeResponse(new Response(false, message));
76
52
  }
77
53
 
78
54
  void Connection::finishCommand(Response *response) {
79
- disconnect(m_page, SIGNAL(loadStarted()), this, SLOT(pageLoadingFromCommand()));
80
- m_command->deleteLater();
81
- m_command = NULL;
82
- if (m_pageLoadingFromCommand)
83
- m_pendingResponse = response;
84
- else
85
- writeResponse(response);
55
+ m_runningCommand->deleteLater();
56
+ writeResponse(response);
86
57
  }
87
58
 
88
59
  void Connection::writeResponse(Response *response) {
@@ -91,7 +62,7 @@ void Connection::writeResponse(Response *response) {
91
62
  else
92
63
  m_socket->write("failure\n");
93
64
 
94
- QByteArray messageUtf8 = response->message().toUtf8();
65
+ QByteArray messageUtf8 = response->message();
95
66
  QString messageLength = QString::number(messageUtf8.size()) + "\n";
96
67
  m_socket->write(messageLength.toAscii());
97
68
  m_socket->write(messageUtf8);
data/src/Connection.h CHANGED
@@ -7,6 +7,7 @@ class Command;
7
7
  class Response;
8
8
  class CommandParser;
9
9
  class CommandFactory;
10
+ class PageLoadingCommand;
10
11
 
11
12
  class Connection : public QObject {
12
13
  Q_OBJECT
@@ -15,25 +16,22 @@ class Connection : public QObject {
15
16
  Connection(QTcpSocket *socket, WebPage *page, QObject *parent = 0);
16
17
 
17
18
  public slots:
18
- void commandReady(QString commandName, QStringList arguments);
19
+ void commandReady(Command *command);
19
20
  void finishCommand(Response *response);
20
21
  void pendingLoadFinished(bool success);
21
- void pageLoadingFromCommand();
22
22
 
23
23
  private:
24
24
  void startCommand();
25
25
  void writeResponse(Response *response);
26
+ void writePageLoadFailure();
26
27
 
27
28
  QTcpSocket *m_socket;
28
- QString m_commandName;
29
- Command *m_command;
30
- QStringList m_arguments;
29
+ Command *m_queuedCommand;
31
30
  WebPage *m_page;
32
31
  CommandParser *m_commandParser;
33
32
  CommandFactory *m_commandFactory;
33
+ PageLoadingCommand *m_runningCommand;
34
34
  bool m_pageSuccess;
35
35
  bool m_commandWaiting;
36
- bool m_pageLoadingFromCommand;
37
- Response *m_pendingResponse;
38
36
  };
39
37
 
@@ -1,11 +1,10 @@
1
1
  #include "ConsoleMessages.h"
2
2
  #include "WebPage.h"
3
3
 
4
- ConsoleMessages::ConsoleMessages(WebPage *page, QObject *parent) : Command(page, parent) {
4
+ ConsoleMessages::ConsoleMessages(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
5
5
  }
6
6
 
7
- void ConsoleMessages::start(QStringList &arguments) {
8
- Q_UNUSED(arguments);
7
+ void ConsoleMessages::start() {
9
8
  emit finished(new Response(true, page()->consoleMessages()));
10
9
  }
11
10
 
@@ -6,7 +6,7 @@ class ConsoleMessages : public Command {
6
6
  Q_OBJECT
7
7
 
8
8
  public:
9
- ConsoleMessages(WebPage *page, QObject *parent = 0);
10
- virtual void start(QStringList &arguments);
9
+ ConsoleMessages(WebPage *page, QStringList &arguments, QObject *parent = 0);
10
+ virtual void start();
11
11
  };
12
12
 
data/src/CurrentUrl.cpp CHANGED
@@ -1,7 +1,7 @@
1
1
  #include "CurrentUrl.h"
2
2
  #include "WebPage.h"
3
3
 
4
- CurrentUrl::CurrentUrl(WebPage *page, QObject *parent) : Command(page, parent) {
4
+ CurrentUrl::CurrentUrl(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
5
5
  }
6
6
 
7
7
  /*
@@ -51,14 +51,11 @@ CurrentUrl::CurrentUrl(WebPage *page, QObject *parent) : Command(page, parent) {
51
51
  * redirect w/o pushState, in which case QWebFrame->url() will have the correct
52
52
  * current_url value. In all other cases QWebFrame->requestedUrl() is correct.
53
53
  */
54
- void CurrentUrl::start(QStringList &arguments) {
55
- Q_UNUSED(arguments);
56
-
54
+ void CurrentUrl::start() {
57
55
  QUrl humanUrl = wasRedirectedAndNotModifiedByJavascript() ?
58
56
  page()->currentFrame()->url() : page()->currentFrame()->requestedUrl();
59
57
  QByteArray encodedBytes = humanUrl.toEncoded();
60
- QString urlString = QString(encodedBytes);
61
- emit finished(new Response(true, urlString));
58
+ emit finished(new Response(true, encodedBytes));
62
59
  }
63
60
 
64
61
  bool CurrentUrl::wasRegularLoad() {
data/src/CurrentUrl.h CHANGED
@@ -6,8 +6,8 @@ class CurrentUrl : public Command {
6
6
  Q_OBJECT
7
7
 
8
8
  public:
9
- CurrentUrl(WebPage *page, QObject *parent = 0);
10
- virtual void start(QStringList &arguments);
9
+ CurrentUrl(WebPage *page, QStringList &arguments, QObject *parent = 0);
10
+ virtual void start();
11
11
 
12
12
  private:
13
13
  bool wasRegularLoad();
data/src/Evaluate.cpp CHANGED
@@ -2,12 +2,12 @@
2
2
  #include "WebPage.h"
3
3
  #include <iostream>
4
4
 
5
- Evaluate::Evaluate(WebPage *page, QObject *parent) : Command(page, parent) {
5
+ Evaluate::Evaluate(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
6
6
  m_buffer = "";
7
7
  }
8
8
 
9
- void Evaluate::start(QStringList &arguments) {
10
- QVariant result = page()->currentFrame()->evaluateJavaScript(arguments[0]);
9
+ void Evaluate::start() {
10
+ QVariant result = page()->currentFrame()->evaluateJavaScript(arguments()[0]);
11
11
  addVariant(result);
12
12
  emit finished(new Response(true, m_buffer));
13
13
  }