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,24 +1,37 @@
1
+ #ifndef _WEBPAGE_H
2
+ #define _WEBPAGE_H
1
3
  #include <QtWebKit>
2
4
 
5
+ class WebPageManager;
6
+
3
7
  class WebPage : public QWebPage {
4
8
  Q_OBJECT
5
9
 
6
10
  public:
7
- WebPage(QObject *parent = 0);
8
- QVariant invokeCapybaraFunction(const char *name, QStringList &arguments);
9
- QVariant invokeCapybaraFunction(QString &name, QStringList &arguments);
11
+ WebPage(WebPageManager *, QObject *parent = 0);
12
+ QVariant invokeCapybaraFunction(const char *name, const QStringList &arguments);
13
+ QVariant invokeCapybaraFunction(QString &name, const QStringList &arguments);
10
14
  QString failureString();
11
15
  QString userAgentForUrl(const QUrl &url ) const;
12
16
  void setUserAgent(QString userAgent);
17
+ void setConfirmAction(QString action);
18
+ void setPromptAction(QString action);
19
+ void setPromptText(QString action);
13
20
  int getLastStatus();
14
- void resetResponseHeaders();
15
21
  void setCustomNetworkAccessManager();
16
22
  bool render(const QString &fileName);
17
23
  virtual bool extension (Extension extension, const ExtensionOption *option=0, ExtensionReturn *output=0);
18
- void ignoreSslErrors();
24
+ void setSkipImageLoading(bool skip);
19
25
  QString consoleMessages();
20
- void resetConsoleMessages();
26
+ QString alertMessages();
27
+ QString confirmMessages();
28
+ QString promptMessages();
21
29
  void resetWindowSize();
30
+ QWebPage *createWindow(WebWindowType type);
31
+ QString uuid();
32
+ QString getWindowName();
33
+ bool matchesWindowSelector(QString);
34
+ void setFocus();
22
35
 
23
36
  public slots:
24
37
  bool shouldInterruptJavaScript();
@@ -26,14 +39,17 @@ class WebPage : public QWebPage {
26
39
  void loadStarted();
27
40
  void loadFinished(bool);
28
41
  bool isLoading() const;
29
- QString pageHeaders();
42
+ const QList<QNetworkReply::RawHeaderPair> &pageHeaders();
30
43
  void frameCreated(QWebFrame *);
31
- void replyFinished(QNetworkReply *reply);
32
44
  void handleSslErrorsForReply(QNetworkReply *reply, const QList<QSslError> &);
33
45
  void handleUnsupportedContent(QNetworkReply *reply);
46
+ void networkAccessManagerCreatedRequest(QByteArray &url, QNetworkReply *reply);
47
+ void networkAccessManagerFinishedReply(QNetworkReply *reply);
34
48
 
35
49
  signals:
36
50
  void pageFinished(bool);
51
+ void requestCreated(QByteArray &url, QNetworkReply *reply);
52
+ void replyFinished(QNetworkReply *reply);
37
53
 
38
54
  protected:
39
55
  virtual void javaScriptConsoleMessage(const QString &message, int lineNumber, const QString &sourceID);
@@ -41,17 +57,27 @@ class WebPage : public QWebPage {
41
57
  virtual bool javaScriptConfirm(QWebFrame *frame, const QString &message);
42
58
  virtual bool javaScriptPrompt(QWebFrame *frame, const QString &message, const QString &defaultValue, QString *result);
43
59
  virtual QString chooseFile(QWebFrame * parentFrame, const QString &suggestedFile);
60
+ virtual bool supportsExtension(Extension extension) const;
44
61
 
45
62
  private:
46
63
  QString m_capybaraJavascript;
47
64
  QString m_userAgent;
48
65
  bool m_loading;
66
+ bool m_failed;
49
67
  QString getLastAttachedFileName();
50
68
  void loadJavascript();
51
69
  void setUserStylesheet();
52
- int m_lastStatus;
53
- QString m_pageHeaders;
54
- bool m_ignoreSslErrors;
70
+ bool m_confirm;
71
+ bool m_prompt;
55
72
  QStringList m_consoleMessages;
73
+ QStringList m_alertMessages;
74
+ QStringList m_confirmMessages;
75
+ QString m_prompt_text;
76
+ QStringList m_promptMessages;
77
+ QString m_uuid;
78
+ WebPageManager *m_manager;
79
+ QString m_errorPageMessage;
56
80
  };
57
81
 
82
+ #endif //_WEBPAGE_H
83
+
@@ -0,0 +1,127 @@
1
+ #include "WebPageManager.h"
2
+ #include "WebPage.h"
3
+ #include "NetworkCookieJar.h"
4
+
5
+ WebPageManager::WebPageManager(QObject *parent) : QObject(parent) {
6
+ m_ignoreSslErrors = false;
7
+ m_cookieJar = new NetworkCookieJar(this);
8
+ m_success = true;
9
+ m_loggingEnabled = false;
10
+ m_ignoredOutput = new QString();
11
+ m_timeout = -1;
12
+ createPage(this)->setFocus();
13
+ }
14
+
15
+ void WebPageManager::append(WebPage *value) {
16
+ m_pages.append(value);
17
+ }
18
+
19
+ QList<WebPage *> WebPageManager::pages() const {
20
+ return m_pages;
21
+ }
22
+
23
+ void WebPageManager::setCurrentPage(WebPage *page) {
24
+ m_currentPage = page;
25
+ }
26
+
27
+ WebPage *WebPageManager::currentPage() const {
28
+ return m_currentPage;
29
+ }
30
+
31
+ WebPage *WebPageManager::createPage(QObject *parent) {
32
+ WebPage *page = new WebPage(this, parent);
33
+ connect(page, SIGNAL(loadStarted()),
34
+ this, SLOT(emitLoadStarted()));
35
+ connect(page, SIGNAL(pageFinished(bool)),
36
+ this, SLOT(setPageStatus(bool)));
37
+ connect(page, SIGNAL(requestCreated(QByteArray &, QNetworkReply *)),
38
+ this, SLOT(requestCreated(QByteArray &, QNetworkReply *)));
39
+ connect(page, SIGNAL(replyFinished(QNetworkReply *)),
40
+ this, SLOT(replyFinished(QNetworkReply *)));
41
+ append(page);
42
+ return page;
43
+ }
44
+
45
+ void WebPageManager::emitLoadStarted() {
46
+ if (m_started.empty()) {
47
+ logger() << "Load started";
48
+ emit loadStarted();
49
+ }
50
+ }
51
+
52
+ void WebPageManager::requestCreated(QByteArray &url, QNetworkReply *reply) {
53
+ logger() << "Started request to" << url;
54
+ m_started += reply;
55
+ }
56
+
57
+ void WebPageManager::replyFinished(QNetworkReply *reply) {
58
+ int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
59
+ logger() << "Received" << status << "from" << reply->url().toString();
60
+ m_started.remove(reply);
61
+ logger() << m_started.size() << "requests remaining";
62
+ if (m_started.empty() && !m_success) {
63
+ emitPageFinished();
64
+ }
65
+ }
66
+
67
+ void WebPageManager::setPageStatus(bool success) {
68
+ logger() << "Page finished with" << success;
69
+ m_success = success && m_success;
70
+ if (m_started.empty()) {
71
+ emitPageFinished();
72
+ }
73
+ }
74
+
75
+ void WebPageManager::emitPageFinished() {
76
+ logger() << "Load finished";
77
+ emit pageFinished(m_success);
78
+ m_success = true;
79
+ }
80
+
81
+ void WebPageManager::setIgnoreSslErrors(bool value) {
82
+ m_ignoreSslErrors = value;
83
+ }
84
+
85
+ bool WebPageManager::ignoreSslErrors() {
86
+ return m_ignoreSslErrors;
87
+ }
88
+
89
+ int WebPageManager::getTimeout() {
90
+ return m_timeout;
91
+ }
92
+
93
+ void WebPageManager::setTimeout(int timeout) {
94
+ m_timeout = timeout;
95
+ }
96
+
97
+ void WebPageManager::reset() {
98
+ m_timeout = -1;
99
+ m_cookieJar->clearCookies();
100
+ m_pages.first()->deleteLater();
101
+ m_pages.clear();
102
+ createPage(this)->setFocus();
103
+ }
104
+
105
+ NetworkCookieJar *WebPageManager::cookieJar() {
106
+ return m_cookieJar;
107
+ }
108
+
109
+ bool WebPageManager::isLoading() const {
110
+ foreach(WebPage *page, pages()) {
111
+ if (page->isLoading()) {
112
+ return true;
113
+ }
114
+ }
115
+ return false;
116
+ }
117
+
118
+ QDebug WebPageManager::logger() const {
119
+ if (m_loggingEnabled)
120
+ return qDebug();
121
+ else
122
+ return QDebug(m_ignoredOutput);
123
+ }
124
+
125
+ void WebPageManager::enableLogging() {
126
+ m_loggingEnabled = true;
127
+ }
@@ -0,0 +1,59 @@
1
+ #ifndef _WEBPAGEMANAGER_H
2
+ #define _WEBPAGEMANAGER_H
3
+ #include <QList>
4
+ #include <QSet>
5
+ #include <QObject>
6
+ #include <QNetworkReply>
7
+ #include <QDebug>
8
+ #include <QFile>
9
+
10
+ class WebPage;
11
+ class NetworkCookieJar;
12
+
13
+ class WebPageManager : public QObject {
14
+ Q_OBJECT
15
+
16
+ public:
17
+ WebPageManager(QObject *parent = 0);
18
+ void append(WebPage *value);
19
+ QList<WebPage *> pages() const;
20
+ void setCurrentPage(WebPage *);
21
+ WebPage *currentPage() const;
22
+ WebPage *createPage(QObject *parent);
23
+ void setIgnoreSslErrors(bool);
24
+ bool ignoreSslErrors();
25
+ void setTimeout(int);
26
+ int getTimeout();
27
+ void reset();
28
+ NetworkCookieJar *cookieJar();
29
+ bool isLoading() const;
30
+ QDebug logger() const;
31
+ void enableLogging();
32
+
33
+ public slots:
34
+ void emitLoadStarted();
35
+ void setPageStatus(bool);
36
+ void requestCreated(QByteArray &url, QNetworkReply *reply);
37
+ void replyFinished(QNetworkReply *reply);
38
+
39
+ signals:
40
+ void pageFinished(bool);
41
+ void loadStarted();
42
+
43
+ private:
44
+ void emitPageFinished();
45
+ static void handleDebugMessage(QtMsgType type, const char *message);
46
+
47
+ QList<WebPage *> m_pages;
48
+ WebPage *m_currentPage;
49
+ bool m_ignoreSslErrors;
50
+ NetworkCookieJar *m_cookieJar;
51
+ QSet<QNetworkReply*> m_started;
52
+ bool m_success;
53
+ bool m_loggingEnabled;
54
+ QString *m_ignoredOutput;
55
+ int m_timeout;
56
+ };
57
+
58
+ #endif // _WEBPAGEMANAGER_H
59
+
@@ -0,0 +1,32 @@
1
+ #include "WindowFocus.h"
2
+ #include "SocketCommand.h"
3
+ #include "WebPage.h"
4
+ #include "CommandFactory.h"
5
+ #include "WebPageManager.h"
6
+
7
+ WindowFocus::WindowFocus(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
8
+ }
9
+
10
+ void WindowFocus::start() {
11
+ focusWindow(arguments()[0]);
12
+ }
13
+
14
+ void WindowFocus::windowNotFound() {
15
+ emit finished(new Response(false, QString("Unable to locate window. ")));
16
+ }
17
+
18
+ void WindowFocus::success(WebPage *page) {
19
+ page->setFocus();
20
+ emit finished(new Response(true));
21
+ }
22
+
23
+ void WindowFocus::focusWindow(QString selector) {
24
+ foreach(WebPage *page, manager()->pages()) {
25
+ if (page->matchesWindowSelector(selector)) {
26
+ success(page);
27
+ return;
28
+ }
29
+ }
30
+
31
+ windowNotFound();
32
+ }
@@ -0,0 +1,15 @@
1
+ #include "SocketCommand.h"
2
+
3
+ class WindowFocus : public SocketCommand {
4
+ Q_OBJECT
5
+
6
+ public:
7
+ WindowFocus(WebPageManager *, QStringList &arguments, QObject *parent = 0);
8
+ virtual void start();
9
+
10
+ private:
11
+ void success(WebPage *);
12
+ void windowNotFound();
13
+ void focusWindow(QString);
14
+ };
15
+
@@ -1,7 +1,8 @@
1
1
  #include "Body.h"
2
2
  #include "WebPage.h"
3
+ #include "WebPageManager.h"
3
4
 
4
- Body::Body(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
5
+ Body::Body(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
5
6
  }
6
7
 
7
8
  void Body::start() {
@@ -11,6 +11,10 @@ Capybara = {
11
11
  return this.findRelativeTo(document, xpath);
12
12
  },
13
13
 
14
+ currentUrl: function () {
15
+ return window.location.toString();
16
+ },
17
+
14
18
  findWithin: function (index, xpath) {
15
19
  return this.findRelativeTo(this.nodes[index], xpath);
16
20
  },
@@ -51,6 +55,10 @@ Capybara = {
51
55
  return this.nodes[index].disabled;
52
56
  break;
53
57
 
58
+ case 'multiple':
59
+ return this.nodes[index].multiple;
60
+ break;
61
+
54
62
  default:
55
63
  return this.nodes[index].getAttribute(name);
56
64
  }
@@ -110,6 +118,7 @@ Capybara = {
110
118
 
111
119
  click: function (index) {
112
120
  this.mousedown(index);
121
+ this.focus(index);
113
122
  this.mouseup(index);
114
123
  var clickEvent = document.createEvent('MouseEvents');
115
124
  clickEvent.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
@@ -148,8 +157,10 @@ Capybara = {
148
157
  visible: function (index) {
149
158
  var element = this.nodes[index];
150
159
  while (element) {
151
- if (element.ownerDocument.defaultView.getComputedStyle(element, null).getPropertyValue("display") == 'none')
160
+ var style = element.ownerDocument.defaultView.getComputedStyle(element, null);
161
+ if (style.getPropertyValue("display") == 'none' || style.getPropertyValue("visibility") == 'hidden')
152
162
  return false;
163
+
153
164
  element = element.parentElement;
154
165
  }
155
166
  return true;
@@ -163,6 +174,15 @@ Capybara = {
163
174
  return this.nodes[index].value;
164
175
  },
165
176
 
177
+ getInnerHTML: function(index) {
178
+ return this.nodes[index].innerHTML;
179
+ },
180
+
181
+ setInnerHTML: function(index, value) {
182
+ this.nodes[index].innerHTML = value;
183
+ return true;
184
+ },
185
+
166
186
  characterToKeyCode: function(character) {
167
187
  var code = character.toUpperCase().charCodeAt(0);
168
188
  var specialKeys = {
@@ -214,7 +234,7 @@ Capybara = {
214
234
  textTypes = ["email", "number", "password", "search", "tel", "text", "textarea", "url"];
215
235
 
216
236
  if (textTypes.indexOf(type) != -1) {
217
- this.trigger(index, "focus");
237
+ this.focus(index);
218
238
 
219
239
  maxLength = this.attribute(index, "maxlength");
220
240
  if (maxLength && value.length > maxLength) {
@@ -233,22 +253,25 @@ Capybara = {
233
253
  this.trigger(index, "input");
234
254
  }
235
255
  this.trigger(index, "change");
236
- this.trigger(index, "blur");
237
256
 
238
257
  } else if (type === "checkbox" || type === "radio") {
239
258
  if (node.checked != (value === "true")) {
240
- this.click(index)
259
+ this.click(index);
241
260
  }
242
261
 
243
262
  } else if (type === "file") {
244
263
  this.lastAttachedFile = value;
245
- this.click(index)
264
+ this.click(index);
246
265
 
247
266
  } else {
248
267
  node.value = value;
249
268
  }
250
269
  },
251
270
 
271
+ focus: function(index) {
272
+ this.nodes[index].focus();
273
+ },
274
+
252
275
  selectOption: function(index) {
253
276
  this.nodes[index].selected = true;
254
277
  this.trigger(index, "change");
@@ -270,7 +293,8 @@ Capybara = {
270
293
  position.x += element.offsetLeft;
271
294
  position.y += element.offsetTop;
272
295
  } while ((element = element.offsetParent));
273
- position.x = Math.floor(position.x), position.y = Math.floor(position.y);
296
+ position.x = Math.floor(position.x);
297
+ position.y = Math.floor(position.y);
274
298
 
275
299
  return position;
276
300
  },
@@ -282,7 +306,9 @@ Capybara = {
282
306
  oldStyle[prop] = element.style[prop];
283
307
  element.style[prop] = newStyle[prop];
284
308
  }
285
- element.offsetWidth, element.offsetHeight; // force reflow
309
+ // force reflow
310
+ element.offsetWidth;
311
+ element.offsetHeight;
286
312
  for (prop in oldStyle)
287
313
  element.style[prop] = oldStyle[prop];
288
314
  }
@@ -299,12 +325,14 @@ Capybara = {
299
325
  var eventObject = document.createEvent("MouseEvents");
300
326
  eventObject.initMouseEvent(eventName, true, true, window, 0, 0, 0, options.clientX || 0, options.clientY || 0, false, false, false, false, 0, null);
301
327
  element.dispatchEvent(eventObject);
302
- }
328
+ };
303
329
  mouseTrigger('mousedown', options);
304
- options.clientX += 1, options.clientY += 1;
330
+ options.clientX += 1;
331
+ options.clientY += 1;
305
332
  mouseTrigger('mousemove', options);
306
333
 
307
- position = this.centerPostion(target), options = {
334
+ position = this.centerPostion(target);
335
+ options = {
308
336
  clientX: position.x,
309
337
  clientY: position.y
310
338
  };