capybara-webkit 1.1.1 → 1.2.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.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/.travis.yml +19 -13
- data/Appraisals +8 -4
- data/Gemfile.lock +29 -14
- data/NEWS.md +4 -0
- data/README.md +1 -1
- data/Rakefile +1 -1
- data/capybara-webkit.gemspec +2 -1
- data/gemfiles/2.0.gemfile.lock +10 -6
- data/gemfiles/2.1.gemfile.lock +22 -9
- data/gemfiles/2.2.gemfile +7 -0
- data/gemfiles/2.2.gemfile.lock +77 -0
- data/gemfiles/2.3.gemfile +7 -0
- data/gemfiles/2.3.gemfile.lock +77 -0
- data/lib/capybara/webkit/browser.rb +28 -4
- data/lib/capybara/webkit/connection.rb +9 -24
- data/lib/capybara/webkit/driver.rb +40 -4
- data/lib/capybara/webkit/errors.rb +3 -0
- data/lib/capybara/webkit/version.rb +1 -1
- data/spec/browser_spec.rb +1 -1
- data/spec/connection_spec.rb +27 -5
- data/spec/driver_rendering_spec.rb +10 -0
- data/spec/driver_resize_window_spec.rb +22 -0
- data/spec/driver_spec.rb +117 -9
- data/spec/selenium_compatibility_spec.rb +3 -0
- data/spec/spec_helper.rb +22 -3
- data/spec/support/matchers/include_response.rb +24 -0
- data/src/CommandFactory.cpp +7 -1
- data/src/GoBack.cpp +12 -0
- data/src/GoBack.h +10 -0
- data/src/GoForward.cpp +12 -0
- data/src/GoForward.h +10 -0
- data/src/Render.cpp +10 -1
- data/src/Reset.cpp +0 -2
- data/src/SocketCommand.cpp +6 -0
- data/src/SocketCommand.h +1 -0
- data/src/StdinNotifier.cpp +16 -0
- data/src/StdinNotifier.h +20 -0
- data/src/WebPage.cpp +20 -5
- data/src/WebPage.h +4 -1
- data/src/WebPageManager.cpp +18 -7
- data/src/WebPageManager.h +2 -1
- data/src/WindowClose.cpp +10 -0
- data/src/WindowClose.h +12 -0
- data/src/WindowCommand.cpp +27 -0
- data/src/WindowCommand.h +21 -0
- data/src/WindowFocus.cpp +2 -25
- data/src/WindowFocus.h +4 -7
- data/src/WindowMaximize.cpp +14 -0
- data/src/WindowMaximize.h +12 -0
- data/src/WindowOpen.cpp +12 -0
- data/src/WindowOpen.h +10 -0
- data/src/WindowResize.cpp +16 -0
- data/src/WindowResize.h +12 -0
- data/src/WindowSize.cpp +17 -0
- data/src/WindowSize.h +12 -0
- data/src/capybara.js +19 -3
- data/src/find_command.h +7 -1
- data/src/main.cpp +4 -0
- data/src/webkit_server.pro +20 -4
- data/templates/Command.cpp +2 -0
- data/templates/Command.h +1 -3
- metadata +82 -54
- data/src/ResizeWindow.cpp +0 -17
- data/src/ResizeWindow.h +0 -10
@@ -10,6 +10,8 @@ describe Capybara::Webkit, 'compatibility with selenium' do
|
|
10
10
|
<label for="one">One</label><input type="text" name="one" id="one" />
|
11
11
|
<label for="two">Two</label><input type="text" name="two" id="two" />
|
12
12
|
<label for="three">Three</label><input type="text" name="three" id="three" readonly="readonly" />
|
13
|
+
<label for="textarea">Textarea</label>
|
14
|
+
<textarea name="textarea" id="textarea"></textarea>
|
13
15
|
<input type="submit" value="Submit" id="submit" />
|
14
16
|
</form>
|
15
17
|
<script type="text/javascript">
|
@@ -35,6 +37,7 @@ describe Capybara::Webkit, 'compatibility with selenium' do
|
|
35
37
|
fill_in "One", :with => "a new value"
|
36
38
|
fill_in "Two", :with => "other value"
|
37
39
|
fill_in "Three", :with => "readonly value"
|
40
|
+
fill_in "Textarea", :with => "last value"
|
38
41
|
click_button "Submit"
|
39
42
|
end
|
40
43
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -10,8 +10,8 @@ $LOAD_PATH << File.join(PROJECT_ROOT, 'lib')
|
|
10
10
|
Dir[File.join(PROJECT_ROOT, 'spec', 'support', '**', '*.rb')].each { |file| require(file) }
|
11
11
|
|
12
12
|
require 'capybara/webkit'
|
13
|
-
|
14
|
-
$webkit_browser = Capybara::Webkit::Browser.new(
|
13
|
+
$webkit_connection = Capybara::Webkit::Connection.new(:socket_class => TCPSocket)
|
14
|
+
$webkit_browser = Capybara::Webkit::Browser.new($webkit_connection)
|
15
15
|
|
16
16
|
if ENV['DEBUG']
|
17
17
|
$webkit_browser.enable_logging
|
@@ -24,8 +24,27 @@ Capybara.register_driver :reusable_webkit do |app|
|
|
24
24
|
end
|
25
25
|
|
26
26
|
RSpec.configure do |c|
|
27
|
-
c.filter_run_excluding :skip_on_windows => !(RbConfig::CONFIG['host_os'] =~ /mingw32/).nil?
|
28
27
|
Capybara::SpecHelper.configure(c)
|
28
|
+
|
29
|
+
c.filter_run_excluding :skip_on_windows => !(RbConfig::CONFIG['host_os'] =~ /mingw32/).nil?
|
30
|
+
c.filter_run_excluding :skip_on_jruby => !defined?(::JRUBY_VERSION).nil?
|
31
|
+
|
32
|
+
# We can't support outerWidth and outerHeight without a visible window.
|
33
|
+
# We focus the next window instead of failing when closing windows.
|
34
|
+
c.filter_run_excluding :full_description =>
|
35
|
+
/Capybara::Session webkit Capybara::Window #(size|resize_to|maximize|close.*no_such_window_error)/
|
36
|
+
|
37
|
+
# Capybara's integration tests expect "capybara/" in the default path
|
38
|
+
c.around :requires => :screenshot do |example|
|
39
|
+
old_path = Capybara.save_and_open_page_path
|
40
|
+
Capybara.save_and_open_page_path = File.join(PROJECT_ROOT, 'tmp', 'capybara')
|
41
|
+
|
42
|
+
begin
|
43
|
+
example.run
|
44
|
+
ensure
|
45
|
+
Capybara.save_and_open_page_path = old_path
|
46
|
+
end
|
47
|
+
end
|
29
48
|
end
|
30
49
|
|
31
50
|
def with_env_vars(vars)
|
@@ -0,0 +1,24 @@
|
|
1
|
+
RSpec::Matchers.define :include_response do |expected_response|
|
2
|
+
read_timeout = 2
|
3
|
+
read_bytes = 4096
|
4
|
+
response = ""
|
5
|
+
|
6
|
+
match do |read_io|
|
7
|
+
found_response = false
|
8
|
+
|
9
|
+
while !found_response && IO.select([read_io], nil, nil, read_timeout) do
|
10
|
+
response += read_io.read_nonblock(read_bytes)
|
11
|
+
found_response = response.include?(expected_response)
|
12
|
+
end
|
13
|
+
|
14
|
+
found_response
|
15
|
+
end
|
16
|
+
|
17
|
+
failure_message_for_should do |actual|
|
18
|
+
"expected #{response} to include #{expected_response}"
|
19
|
+
end
|
20
|
+
|
21
|
+
failure_message_for_should_not do |actual|
|
22
|
+
"expected #{response} to not include #{expected_response}"
|
23
|
+
end
|
24
|
+
end
|
data/src/CommandFactory.cpp
CHANGED
@@ -20,7 +20,7 @@
|
|
20
20
|
#include "CurrentUrl.h"
|
21
21
|
#include "SetTimeout.h"
|
22
22
|
#include "GetTimeout.h"
|
23
|
-
#include "
|
23
|
+
#include "WindowResize.h"
|
24
24
|
#include "IgnoreSslErrors.h"
|
25
25
|
#include "SetSkipImageLoading.h"
|
26
26
|
#include "WindowFocus.h"
|
@@ -40,6 +40,12 @@
|
|
40
40
|
#include "Version.h"
|
41
41
|
#include "Title.h"
|
42
42
|
#include "FindCss.h"
|
43
|
+
#include "WindowClose.h"
|
44
|
+
#include "WindowOpen.h"
|
45
|
+
#include "WindowSize.h"
|
46
|
+
#include "WindowMaximize.h"
|
47
|
+
#include "GoBack.h"
|
48
|
+
#include "GoForward.h"
|
43
49
|
|
44
50
|
CommandFactory::CommandFactory(WebPageManager *manager, QObject *parent) : QObject(parent) {
|
45
51
|
m_manager = manager;
|
data/src/GoBack.cpp
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
#include "GoBack.h"
|
2
|
+
#include "SocketCommand.h"
|
3
|
+
#include "WebPage.h"
|
4
|
+
#include "WebPageManager.h"
|
5
|
+
|
6
|
+
GoBack::GoBack(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
|
7
|
+
}
|
8
|
+
|
9
|
+
void GoBack::start() {
|
10
|
+
page()->triggerAction(QWebPage::Back);
|
11
|
+
finish(true);
|
12
|
+
}
|
data/src/GoBack.h
ADDED
data/src/GoForward.cpp
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
#include "GoForward.h"
|
2
|
+
#include "SocketCommand.h"
|
3
|
+
#include "WebPage.h"
|
4
|
+
#include "WebPageManager.h"
|
5
|
+
|
6
|
+
GoForward::GoForward(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
|
7
|
+
}
|
8
|
+
|
9
|
+
void GoForward::start() {
|
10
|
+
page()->triggerAction(QWebPage::Forward);
|
11
|
+
finish(true);
|
12
|
+
}
|
data/src/GoForward.h
ADDED
data/src/Render.cpp
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
#include "Render.h"
|
2
2
|
#include "WebPage.h"
|
3
3
|
#include "WebPageManager.h"
|
4
|
+
#include "ErrorMessage.h"
|
4
5
|
|
5
6
|
Render::Render(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
|
6
7
|
}
|
@@ -14,5 +15,13 @@ void Render::start() {
|
|
14
15
|
|
15
16
|
bool result = page()->render( imagePath, size );
|
16
17
|
|
17
|
-
|
18
|
+
if (result) {
|
19
|
+
finish(true);
|
20
|
+
} else {
|
21
|
+
const QString failure = QString("Unable to save %1x%2 image to %3").
|
22
|
+
arg(width).
|
23
|
+
arg(height).
|
24
|
+
arg(imagePath);
|
25
|
+
finish(false, new ErrorMessage(failure));
|
26
|
+
}
|
18
27
|
}
|
data/src/Reset.cpp
CHANGED
data/src/SocketCommand.cpp
CHANGED
@@ -19,3 +19,9 @@ WebPageManager *SocketCommand::manager() const {
|
|
19
19
|
return m_manager;
|
20
20
|
}
|
21
21
|
|
22
|
+
QString SocketCommand::toString() const {
|
23
|
+
QString result;
|
24
|
+
QTextStream(&result) << metaObject()->className() << QString("(") << m_arguments.join(", ") << QString(")");
|
25
|
+
return result;
|
26
|
+
}
|
27
|
+
|
data/src/SocketCommand.h
CHANGED
@@ -0,0 +1,16 @@
|
|
1
|
+
#include "StdinNotifier.h"
|
2
|
+
|
3
|
+
#include <QTcpServer>
|
4
|
+
|
5
|
+
StdinNotifier::StdinNotifier(QObject *parent) : QObject(parent) {
|
6
|
+
m_notifier = new QSocketNotifier(fileno(stdin), QSocketNotifier::Read, this);
|
7
|
+
connect(m_notifier, SIGNAL(activated(int)), this, SLOT(notifierActivated()));
|
8
|
+
}
|
9
|
+
|
10
|
+
void StdinNotifier::notifierActivated() {
|
11
|
+
std::string line;
|
12
|
+
std::getline(std::cin, line);
|
13
|
+
if (std::cin.eof()) {
|
14
|
+
emit eof();
|
15
|
+
}
|
16
|
+
}
|
data/src/StdinNotifier.h
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
#include <QObject>
|
2
|
+
|
3
|
+
class QSocketNotifier;
|
4
|
+
|
5
|
+
class StdinNotifier : public QObject {
|
6
|
+
Q_OBJECT
|
7
|
+
|
8
|
+
public:
|
9
|
+
StdinNotifier(QObject *parent = 0);
|
10
|
+
|
11
|
+
public slots:
|
12
|
+
void notifierActivated();
|
13
|
+
|
14
|
+
signals:
|
15
|
+
void eof();
|
16
|
+
|
17
|
+
private:
|
18
|
+
QSocketNotifier *m_notifier;
|
19
|
+
};
|
20
|
+
|
data/src/WebPage.cpp
CHANGED
@@ -11,6 +11,8 @@
|
|
11
11
|
#include <QWebSettings>
|
12
12
|
#include <QUuid>
|
13
13
|
#include <QApplication>
|
14
|
+
#include <QWebView>
|
15
|
+
#include <QMainWindow>
|
14
16
|
|
15
17
|
WebPage::WebPage(WebPageManager *manager, QObject *parent) : QWebPage(parent) {
|
16
18
|
m_loading = false;
|
@@ -33,14 +35,23 @@ WebPage::WebPage(WebPageManager *manager, QObject *parent) : QWebPage(parent) {
|
|
33
35
|
this, SLOT(frameCreated(QWebFrame *)));
|
34
36
|
connect(this, SIGNAL(unsupportedContent(QNetworkReply*)),
|
35
37
|
this, SLOT(handleUnsupportedContent(QNetworkReply*)));
|
36
|
-
|
38
|
+
connect(this, SIGNAL(windowCloseRequested()), this, SLOT(remove()));
|
37
39
|
|
38
40
|
settings()->setAttribute(QWebSettings::JavascriptCanOpenWindows, true);
|
41
|
+
settings()->setAttribute(QWebSettings::JavascriptCanCloseWindows, true);
|
42
|
+
settings()->setAttribute(QWebSettings::LocalStorageDatabaseEnabled, true);
|
43
|
+
|
44
|
+
createWindow();
|
45
|
+
}
|
46
|
+
|
47
|
+
void WebPage::createWindow() {
|
48
|
+
QSize size(1680, 1050);
|
49
|
+
setViewportSize(size);
|
39
50
|
}
|
40
51
|
|
41
|
-
void WebPage::
|
42
|
-
|
43
|
-
|
52
|
+
void WebPage::resize(int width, int height) {
|
53
|
+
QSize size(width, height);
|
54
|
+
setViewportSize(size);
|
44
55
|
}
|
45
56
|
|
46
57
|
void WebPage::resetLocalStorage() {
|
@@ -334,7 +345,7 @@ bool WebPage::supportsExtension(Extension extension) const {
|
|
334
345
|
|
335
346
|
QWebPage *WebPage::createWindow(WebWindowType type) {
|
336
347
|
Q_UNUSED(type);
|
337
|
-
return m_manager->createPage(
|
348
|
+
return m_manager->createPage();
|
338
349
|
}
|
339
350
|
|
340
351
|
QString WebPage::uuid() {
|
@@ -361,6 +372,10 @@ void WebPage::setFocus() {
|
|
361
372
|
m_manager->setCurrentPage(this);
|
362
373
|
}
|
363
374
|
|
375
|
+
void WebPage::remove() {
|
376
|
+
m_manager->removePage(this);
|
377
|
+
}
|
378
|
+
|
364
379
|
void WebPage::setConfirmAction(QString action) {
|
365
380
|
m_confirm = (action == "Yes");
|
366
381
|
}
|
data/src/WebPage.h
CHANGED
@@ -10,6 +10,7 @@
|
|
10
10
|
class WebPageManager;
|
11
11
|
class InvocationResult;
|
12
12
|
class NetworkReplyProxy;
|
13
|
+
class QWebView;
|
13
14
|
|
14
15
|
class WebPage : public QWebPage {
|
15
16
|
Q_OBJECT
|
@@ -33,7 +34,7 @@ class WebPage : public QWebPage {
|
|
33
34
|
QVariantList alertMessages();
|
34
35
|
QVariantList confirmMessages();
|
35
36
|
QVariantList promptMessages();
|
36
|
-
void
|
37
|
+
void createWindow();
|
37
38
|
void resetLocalStorage();
|
38
39
|
QWebPage *createWindow(WebWindowType type);
|
39
40
|
QString uuid();
|
@@ -46,6 +47,7 @@ class WebPage : public QWebPage {
|
|
46
47
|
QString contentType();
|
47
48
|
void mouseEvent(QEvent::Type type, const QPoint &position, Qt::MouseButton button);
|
48
49
|
bool clickTest(QWebElement element, int absoluteX, int absoluteY);
|
50
|
+
void resize(int, int);
|
49
51
|
|
50
52
|
public slots:
|
51
53
|
bool shouldInterruptJavaScript();
|
@@ -57,6 +59,7 @@ class WebPage : public QWebPage {
|
|
57
59
|
void handleSslErrorsForReply(QNetworkReply *reply, const QList<QSslError> &);
|
58
60
|
void handleUnsupportedContent(QNetworkReply *reply);
|
59
61
|
void replyFinished(QUrl &, QNetworkReply *);
|
62
|
+
void remove();
|
60
63
|
|
61
64
|
signals:
|
62
65
|
void pageFinished(bool);
|
data/src/WebPageManager.cpp
CHANGED
@@ -12,7 +12,7 @@ WebPageManager::WebPageManager(QObject *parent) : QObject(parent) {
|
|
12
12
|
m_timeout = -1;
|
13
13
|
m_networkAccessManager = new NetworkAccessManager(this);
|
14
14
|
m_networkAccessManager->setCookieJar(m_cookieJar);
|
15
|
-
createPage(
|
15
|
+
createPage()->setFocus();
|
16
16
|
}
|
17
17
|
|
18
18
|
NetworkAccessManager *WebPageManager::networkAccessManager() {
|
@@ -35,8 +35,8 @@ WebPage *WebPageManager::currentPage() const {
|
|
35
35
|
return m_currentPage;
|
36
36
|
}
|
37
37
|
|
38
|
-
WebPage *WebPageManager::createPage(
|
39
|
-
WebPage *page = new WebPage(this
|
38
|
+
WebPage *WebPageManager::createPage() {
|
39
|
+
WebPage *page = new WebPage(this);
|
40
40
|
connect(page, SIGNAL(loadStarted()),
|
41
41
|
this, SLOT(emitLoadStarted()));
|
42
42
|
connect(page, SIGNAL(pageFinished(bool)),
|
@@ -47,6 +47,15 @@ WebPage *WebPageManager::createPage(QObject *parent) {
|
|
47
47
|
return page;
|
48
48
|
}
|
49
49
|
|
50
|
+
void WebPageManager::removePage(WebPage *page) {
|
51
|
+
m_pages.removeOne(page);
|
52
|
+
page->deleteLater();
|
53
|
+
if (m_pages.isEmpty())
|
54
|
+
createPage()->setFocus();
|
55
|
+
else if (page == m_currentPage)
|
56
|
+
m_pages.first()->setFocus();
|
57
|
+
}
|
58
|
+
|
50
59
|
void WebPageManager::emitLoadStarted() {
|
51
60
|
if (m_started.empty()) {
|
52
61
|
logger() << "Load started";
|
@@ -110,10 +119,12 @@ void WebPageManager::reset() {
|
|
110
119
|
m_timeout = -1;
|
111
120
|
m_cookieJar->clearCookies();
|
112
121
|
m_networkAccessManager->reset();
|
113
|
-
|
114
|
-
m_pages.
|
115
|
-
|
116
|
-
|
122
|
+
m_currentPage->resetLocalStorage();
|
123
|
+
while (!m_pages.isEmpty()) {
|
124
|
+
WebPage *page = m_pages.takeFirst();
|
125
|
+
page->deleteLater();
|
126
|
+
}
|
127
|
+
createPage()->setFocus();
|
117
128
|
}
|
118
129
|
|
119
130
|
NetworkCookieJar *WebPageManager::cookieJar() {
|
data/src/WebPageManager.h
CHANGED
@@ -20,7 +20,8 @@ class WebPageManager : public QObject {
|
|
20
20
|
QList<WebPage *> pages() const;
|
21
21
|
void setCurrentPage(WebPage *);
|
22
22
|
WebPage *currentPage() const;
|
23
|
-
WebPage *createPage(
|
23
|
+
WebPage *createPage();
|
24
|
+
void removePage(WebPage *);
|
24
25
|
void setIgnoreSslErrors(bool);
|
25
26
|
bool ignoreSslErrors();
|
26
27
|
void setTimeout(int);
|
data/src/WindowClose.cpp
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
#include "WindowClose.h"
|
2
|
+
#include "WebPage.h"
|
3
|
+
|
4
|
+
WindowClose::WindowClose(WebPageManager *manager, QStringList &arguments, QObject *parent) : WindowCommand(manager, arguments, parent) {
|
5
|
+
}
|
6
|
+
|
7
|
+
void WindowClose::windowFound(WebPage *page) {
|
8
|
+
page->remove();
|
9
|
+
finish(true);
|
10
|
+
}
|
data/src/WindowClose.h
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#include "WindowCommand.h"
|
2
|
+
#include "WebPage.h"
|
3
|
+
#include "WebPageManager.h"
|
4
|
+
#include "ErrorMessage.h"
|
5
|
+
|
6
|
+
WindowCommand::WindowCommand(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
|
7
|
+
}
|
8
|
+
|
9
|
+
void WindowCommand::start() {
|
10
|
+
findWindow(arguments()[0]);
|
11
|
+
}
|
12
|
+
|
13
|
+
void WindowCommand::findWindow(QString selector) {
|
14
|
+
foreach(WebPage *page, manager()->pages()) {
|
15
|
+
if (page->matchesWindowSelector(selector)) {
|
16
|
+
windowFound(page);
|
17
|
+
return;
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
21
|
+
windowNotFound();
|
22
|
+
}
|
23
|
+
|
24
|
+
void WindowCommand::windowNotFound() {
|
25
|
+
finish(false,
|
26
|
+
new ErrorMessage("NoSuchWindowError", "Unable to locate window."));
|
27
|
+
}
|