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