capybara-webkit 0.11.0 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
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
  }