capybara-webkit 0.1.7 → 0.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.
- data/capybara-webkit.gemspec +3 -2
- data/lib/capybara/driver/webkit.rb +7 -2
- data/lib/capybara/driver/webkit/browser.rb +10 -0
- data/spec/driver_spec.rb +98 -0
- data/spec/integration/session_spec.rb +18 -2
- data/src/Connection.cpp +5 -3
- data/src/Evaluate.cpp +1 -1
- data/src/Execute.cpp +1 -1
- data/src/FrameFocus.cpp +69 -0
- data/src/FrameFocus.h +28 -0
- data/src/Reset.cpp +1 -1
- data/src/Source.cpp +1 -1
- data/src/Url.cpp +1 -1
- data/src/Visit.cpp +1 -1
- data/src/WebPage.cpp +12 -6
- data/src/WebPage.h +1 -0
- data/src/find_command.h +1 -0
- data/src/webkit_server.pro +2 -2
- metadata +25 -7
data/capybara-webkit.gemspec
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "capybara-webkit"
|
3
|
-
s.version = "0.
|
4
|
-
s.authors = ["thoughtbot", "Joe Ferris", "Jason Morrison", "Tristan Dunn"
|
3
|
+
s.version = "0.2.0"
|
4
|
+
s.authors = ["thoughtbot", "Joe Ferris", "Jason Morrison", "Tristan Dunn",
|
5
|
+
"Joshua Clayton", "Yuichi Tateno", "Aaron Gibralter"]
|
5
6
|
s.email = "support@thoughtbot.com"
|
6
7
|
s.files = `git ls-files`.split("\n")
|
7
8
|
s.test_files = `git ls-files -- {spec,features}/*`.split("\n")
|
@@ -52,8 +52,13 @@ class Capybara::Driver::Webkit
|
|
52
52
|
raise Capybara::NotSupportedByDriverError
|
53
53
|
end
|
54
54
|
|
55
|
-
def within_frame(
|
56
|
-
|
55
|
+
def within_frame(frame_id_or_index)
|
56
|
+
browser.frame_focus(frame_id_or_index)
|
57
|
+
begin
|
58
|
+
yield
|
59
|
+
ensure
|
60
|
+
browser.frame_focus
|
61
|
+
end
|
57
62
|
end
|
58
63
|
|
59
64
|
def within_window(handle)
|
@@ -30,6 +30,16 @@ class Capybara::Driver::Webkit
|
|
30
30
|
command("Url")
|
31
31
|
end
|
32
32
|
|
33
|
+
def frame_focus(frame_id_or_index=nil)
|
34
|
+
if frame_id_or_index.is_a? Fixnum
|
35
|
+
command("FrameFocus", "", frame_id_or_index.to_s)
|
36
|
+
elsif frame_id_or_index
|
37
|
+
command("FrameFocus", frame_id_or_index)
|
38
|
+
else
|
39
|
+
command("FrameFocus")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
33
43
|
def command(name, *args)
|
34
44
|
@socket.puts name
|
35
45
|
@socket.puts args.size
|
data/spec/driver_spec.rb
CHANGED
@@ -6,6 +6,104 @@ describe Capybara::Driver::Webkit do
|
|
6
6
|
before { subject.visit("/hello/world?success=true") }
|
7
7
|
after { subject.reset! }
|
8
8
|
|
9
|
+
context "iframe app" do
|
10
|
+
before(:all) do
|
11
|
+
@app = lambda do |env|
|
12
|
+
params = ::Rack::Utils.parse_query(env['QUERY_STRING'])
|
13
|
+
if params["iframe"] == "true"
|
14
|
+
# We are in an iframe request.
|
15
|
+
p_id = "farewell"
|
16
|
+
msg = "goodbye"
|
17
|
+
iframe = nil
|
18
|
+
else
|
19
|
+
# We are not in an iframe request and need to make an iframe!
|
20
|
+
p_id = "greeting"
|
21
|
+
msg = "hello"
|
22
|
+
iframe = "<iframe id=\"f\" src=\"/?iframe=true\"></iframe>"
|
23
|
+
end
|
24
|
+
body = <<-HTML
|
25
|
+
<html>
|
26
|
+
<head>
|
27
|
+
<style type="text/css">
|
28
|
+
#display_none { display: none }
|
29
|
+
</style>
|
30
|
+
</head>
|
31
|
+
<body>
|
32
|
+
#{iframe}
|
33
|
+
<script type="text/javascript">
|
34
|
+
document.write("<p id='#{p_id}'>#{msg}</p>");
|
35
|
+
</script>
|
36
|
+
</body>
|
37
|
+
</html>
|
38
|
+
HTML
|
39
|
+
[200,
|
40
|
+
{ 'Content-Type' => 'text/html', 'Content-Length' => body.length.to_s },
|
41
|
+
[body]]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
it "finds frames by index" do
|
46
|
+
subject.within_frame(0) do
|
47
|
+
subject.find("//*[contains(., 'goodbye')]").should_not be_empty
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it "finds frames by id" do
|
52
|
+
subject.within_frame("f") do
|
53
|
+
subject.find("//*[contains(., 'goodbye')]").should_not be_empty
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
it "raises error for missing frame by index" do
|
58
|
+
expect { subject.within_frame(1) { } }.
|
59
|
+
to raise_error(Capybara::Driver::Webkit::WebkitError)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "raise_error for missing frame by id" do
|
63
|
+
expect { subject.within_frame("foo") { } }.
|
64
|
+
to raise_error(Capybara::Driver::Webkit::WebkitError)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "returns an attribute's value" do
|
68
|
+
subject.within_frame("f") do
|
69
|
+
subject.find("//p").first["id"].should == "farewell"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
it "returns a node's text" do
|
74
|
+
subject.within_frame("f") do
|
75
|
+
subject.find("//p").first.text.should == "goodbye"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
it "returns the current URL" do
|
80
|
+
subject.within_frame("f") do
|
81
|
+
port = subject.instance_variable_get("@rack_server").port
|
82
|
+
subject.current_url.should == "http://127.0.0.1:#{port}/?iframe=true"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
it "returns the source code for the page" do
|
87
|
+
subject.within_frame("f") do
|
88
|
+
subject.source.should =~ %r{<html>.*farewell.*}m
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
it "evaluates Javascript" do
|
93
|
+
subject.within_frame("f") do
|
94
|
+
result = subject.evaluate_script(%<document.getElementById('farewell').innerText>)
|
95
|
+
result.should == "goodbye"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
it "executes Javascript" do
|
100
|
+
subject.within_frame("f") do
|
101
|
+
subject.execute_script(%<document.getElementById('farewell').innerHTML = 'yo'>)
|
102
|
+
subject.find("//p[contains(., 'yo')]").should_not be_empty
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
9
107
|
context "hello app" do
|
10
108
|
before(:all) do
|
11
109
|
@app = lambda do |env|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# -*- encoding: UTF-8 -*-
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
require 'capybara-webkit'
|
3
5
|
|
@@ -50,18 +52,32 @@ describe Capybara::Session do
|
|
50
52
|
body = <<-HTML
|
51
53
|
<html><body>
|
52
54
|
<strong>Hello</strong>
|
55
|
+
<span>UTF8文字列</span>
|
56
|
+
<input type="button" value="ボタン" />
|
53
57
|
</body></html>
|
54
58
|
HTML
|
55
59
|
[200,
|
56
|
-
{ 'Content-Type' => 'text/html', 'Content-Length' => body.length.to_s },
|
60
|
+
{ 'Content-Type' => 'text/html; charset=UTF-8', 'Content-Length' => body.length.to_s },
|
57
61
|
[body]]
|
58
62
|
end
|
59
63
|
end
|
60
64
|
|
61
|
-
|
65
|
+
before do
|
62
66
|
subject.visit("/")
|
67
|
+
end
|
68
|
+
|
69
|
+
it "inspects nodes" do
|
63
70
|
subject.all(:xpath, "//strong").first.inspect.should include("strong")
|
64
71
|
end
|
72
|
+
|
73
|
+
it "can read utf8 string" do
|
74
|
+
utf8str = subject.all(:xpath, "//span").first.text
|
75
|
+
utf8str.should eq('UTF8文字列')
|
76
|
+
end
|
77
|
+
|
78
|
+
it "can click utf8 string" do
|
79
|
+
subject.click_button('ボタン')
|
80
|
+
end
|
65
81
|
end
|
66
82
|
end
|
67
83
|
|
data/src/Connection.cpp
CHANGED
@@ -9,6 +9,7 @@
|
|
9
9
|
#include "Source.h"
|
10
10
|
#include "Evaluate.h"
|
11
11
|
#include "Execute.h"
|
12
|
+
#include "FrameFocus.h"
|
12
13
|
|
13
14
|
#include <QTcpSocket>
|
14
15
|
#include <iostream>
|
@@ -69,7 +70,7 @@ void Connection::processArgument(const char *data) {
|
|
69
70
|
} else if (m_expectingDataSize == -1) {
|
70
71
|
m_expectingDataSize = QString(data).toInt();
|
71
72
|
} else {
|
72
|
-
m_arguments.append(data);
|
73
|
+
m_arguments.append(QString::fromUtf8(data));
|
73
74
|
}
|
74
75
|
|
75
76
|
if (m_arguments.length() == m_argumentsExpected) {
|
@@ -123,8 +124,9 @@ void Connection::writeResponse(bool success, QString &response) {
|
|
123
124
|
else
|
124
125
|
m_socket->write("failure\n");
|
125
126
|
|
126
|
-
|
127
|
+
QByteArray response_utf8 = response.toUtf8();
|
128
|
+
QString responseLength = QString::number(response_utf8.size()) + "\n";
|
127
129
|
m_socket->write(responseLength.toAscii());
|
128
|
-
m_socket->write(
|
130
|
+
m_socket->write(response_utf8);
|
129
131
|
}
|
130
132
|
|
data/src/Evaluate.cpp
CHANGED
@@ -7,7 +7,7 @@ Evaluate::Evaluate(WebPage *page, QObject *parent) : Command(page, parent) {
|
|
7
7
|
}
|
8
8
|
|
9
9
|
void Evaluate::start(QStringList &arguments) {
|
10
|
-
QVariant result = page()->
|
10
|
+
QVariant result = page()->currentFrame()->evaluateJavaScript(arguments[0]);
|
11
11
|
addVariant(result);
|
12
12
|
emit finished(true, m_buffer);
|
13
13
|
}
|
data/src/Execute.cpp
CHANGED
@@ -6,7 +6,7 @@ Execute::Execute(WebPage *page, QObject *parent) : Command(page, parent) {
|
|
6
6
|
|
7
7
|
void Execute::start(QStringList &arguments) {
|
8
8
|
QString script = arguments[0] + QString("; 'success'");
|
9
|
-
QVariant result = page()->
|
9
|
+
QVariant result = page()->currentFrame()->evaluateJavaScript(script);
|
10
10
|
QString response;
|
11
11
|
if (result.isValid()) {
|
12
12
|
emit finished(true, response);
|
data/src/FrameFocus.cpp
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
#include "FrameFocus.h"
|
2
|
+
#include "Command.h"
|
3
|
+
#include "WebPage.h"
|
4
|
+
|
5
|
+
FrameFocus::FrameFocus(WebPage *page, QObject *parent) : Command(page, parent) {
|
6
|
+
}
|
7
|
+
|
8
|
+
void FrameFocus::start(QStringList &arguments) {
|
9
|
+
findFrames();
|
10
|
+
switch(arguments.length()) {
|
11
|
+
case 1:
|
12
|
+
focusId(arguments[0]);
|
13
|
+
break;
|
14
|
+
case 2:
|
15
|
+
focusIndex(arguments[1].toInt());
|
16
|
+
break;
|
17
|
+
default:
|
18
|
+
focusParent();
|
19
|
+
}
|
20
|
+
}
|
21
|
+
|
22
|
+
void FrameFocus::findFrames() {
|
23
|
+
frames = page()->currentFrame()->childFrames();
|
24
|
+
}
|
25
|
+
|
26
|
+
void FrameFocus::focusIndex(int index) {
|
27
|
+
if (isFrameAtIndex(index)) {
|
28
|
+
frames[index]->setFocus();
|
29
|
+
success();
|
30
|
+
} else {
|
31
|
+
frameNotFound();
|
32
|
+
}
|
33
|
+
}
|
34
|
+
|
35
|
+
bool FrameFocus::isFrameAtIndex(int index) {
|
36
|
+
return 0 <= index && index < frames.length();
|
37
|
+
}
|
38
|
+
|
39
|
+
void FrameFocus::focusId(QString name) {
|
40
|
+
for (int i = 0; i < frames.length(); i++) {
|
41
|
+
if (frames[i]->frameName().compare(name) == 0) {
|
42
|
+
frames[i]->setFocus();
|
43
|
+
success();
|
44
|
+
return;
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
frameNotFound();
|
49
|
+
}
|
50
|
+
|
51
|
+
void FrameFocus::focusParent() {
|
52
|
+
if (page()->currentFrame()->parentFrame() == 0) {
|
53
|
+
QString response = "Already at parent frame.";
|
54
|
+
emit finished(false, response);
|
55
|
+
} else {
|
56
|
+
page()->currentFrame()->parentFrame()->setFocus();
|
57
|
+
success();
|
58
|
+
}
|
59
|
+
}
|
60
|
+
|
61
|
+
void FrameFocus::frameNotFound() {
|
62
|
+
QString response = "Unable to locate frame. ";
|
63
|
+
emit finished(false, response);
|
64
|
+
}
|
65
|
+
|
66
|
+
void FrameFocus::success() {
|
67
|
+
QString response;
|
68
|
+
emit finished(true, response);
|
69
|
+
}
|
data/src/FrameFocus.h
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
#include "Command.h"
|
2
|
+
|
3
|
+
class WebPage;
|
4
|
+
class QWebFrame;
|
5
|
+
|
6
|
+
class FrameFocus : public Command {
|
7
|
+
Q_OBJECT
|
8
|
+
|
9
|
+
public:
|
10
|
+
FrameFocus(WebPage *page, QObject *parent = 0);
|
11
|
+
virtual void start(QStringList &arguments);
|
12
|
+
|
13
|
+
private:
|
14
|
+
void findFrames();
|
15
|
+
|
16
|
+
void focusParent();
|
17
|
+
|
18
|
+
void focusIndex(int index);
|
19
|
+
bool isFrameAtIndex(int index);
|
20
|
+
|
21
|
+
void focusId(QString id);
|
22
|
+
|
23
|
+
void success();
|
24
|
+
void frameNotFound();
|
25
|
+
|
26
|
+
QList<QWebFrame *> frames;
|
27
|
+
};
|
28
|
+
|
data/src/Reset.cpp
CHANGED
@@ -8,7 +8,7 @@ void Reset::start(QStringList &arguments) {
|
|
8
8
|
Q_UNUSED(arguments);
|
9
9
|
|
10
10
|
page()->triggerAction(QWebPage::Stop);
|
11
|
-
page()->
|
11
|
+
page()->currentFrame()->setHtml("<html><body></body></html>");
|
12
12
|
page()->networkAccessManager()->setCookieJar(new QNetworkCookieJar());
|
13
13
|
QString response = "";
|
14
14
|
emit finished(true, response);
|
data/src/Source.cpp
CHANGED
@@ -7,7 +7,7 @@ Source::Source(WebPage *page, QObject *parent) : Command(page, parent) {
|
|
7
7
|
void Source::start(QStringList &arguments) {
|
8
8
|
Q_UNUSED(arguments)
|
9
9
|
|
10
|
-
QString response = page()->
|
10
|
+
QString response = page()->currentFrame()->toHtml();
|
11
11
|
|
12
12
|
emit finished(true, response);
|
13
13
|
}
|
data/src/Url.cpp
CHANGED
@@ -7,7 +7,7 @@ Url::Url(WebPage *page, QObject *parent) : Command(page, parent) {
|
|
7
7
|
void Url::start(QStringList &argments) {
|
8
8
|
Q_UNUSED(argments);
|
9
9
|
|
10
|
-
QUrl humanUrl = page()->
|
10
|
+
QUrl humanUrl = page()->currentFrame()->url();
|
11
11
|
QByteArray encodedBytes = humanUrl.toEncoded();
|
12
12
|
QString response = QString(encodedBytes);
|
13
13
|
|
data/src/Visit.cpp
CHANGED
@@ -7,7 +7,7 @@ Visit::Visit(WebPage *page, QObject *parent) : Command(page, parent) {
|
|
7
7
|
}
|
8
8
|
|
9
9
|
void Visit::start(QStringList &arguments) {
|
10
|
-
page()->
|
10
|
+
page()->currentFrame()->setUrl(QUrl(arguments[0]));
|
11
11
|
}
|
12
12
|
|
13
13
|
void Visit::loadFinished(bool success) {
|
data/src/WebPage.cpp
CHANGED
@@ -4,8 +4,6 @@
|
|
4
4
|
#include <iostream>
|
5
5
|
|
6
6
|
WebPage::WebPage(QObject *parent) : QWebPage(parent) {
|
7
|
-
connect(mainFrame(), SIGNAL(javaScriptWindowObjectCleared()),
|
8
|
-
this, SLOT(injectJavascriptHelpers()));
|
9
7
|
QResource javascript(":/capybara.js");
|
10
8
|
char * javascriptString = new char[javascript.size() + 1];
|
11
9
|
strcpy(javascriptString, (const char *)javascript.data());
|
@@ -14,10 +12,18 @@ WebPage::WebPage(QObject *parent) : QWebPage(parent) {
|
|
14
12
|
m_loading = false;
|
15
13
|
connect(this, SIGNAL(loadStarted()), this, SLOT(loadStarted()));
|
16
14
|
connect(this, SIGNAL(loadFinished(bool)), this, SLOT(loadFinished(bool)));
|
15
|
+
connect(this, SIGNAL(frameCreated(QWebFrame *)),
|
16
|
+
this, SLOT(frameCreated(QWebFrame *)));
|
17
|
+
}
|
18
|
+
|
19
|
+
void WebPage::frameCreated(QWebFrame * frame) {
|
20
|
+
connect(frame, SIGNAL(javaScriptWindowObjectCleared()),
|
21
|
+
this, SLOT(injectJavascriptHelpers()));
|
17
22
|
}
|
18
23
|
|
19
24
|
void WebPage::injectJavascriptHelpers() {
|
20
|
-
|
25
|
+
QWebFrame* frame = qobject_cast<QWebFrame *>(QObject::sender());
|
26
|
+
frame->evaluateJavaScript(m_capybaraJavascript);
|
21
27
|
}
|
22
28
|
|
23
29
|
bool WebPage::shouldInterruptJavaScript() {
|
@@ -28,9 +34,9 @@ QVariant WebPage::invokeCapybaraFunction(const char *name, QStringList &argument
|
|
28
34
|
QString qname(name);
|
29
35
|
QString objectName("CapybaraInvocation");
|
30
36
|
JavascriptInvocation invocation(qname, arguments);
|
31
|
-
|
37
|
+
currentFrame()->addToJavaScriptWindowObject(objectName, &invocation);
|
32
38
|
QString javascript = QString("Capybara.invoke()");
|
33
|
-
return
|
39
|
+
return currentFrame()->evaluateJavaScript(javascript);
|
34
40
|
}
|
35
41
|
|
36
42
|
QVariant WebPage::invokeCapybaraFunction(QString &name, QStringList &arguments) {
|
@@ -76,6 +82,6 @@ bool WebPage::isLoading() const {
|
|
76
82
|
}
|
77
83
|
|
78
84
|
QString WebPage::failureString() {
|
79
|
-
return QString("Unable to load URL: ") +
|
85
|
+
return QString("Unable to load URL: ") + currentFrame()->url().toString();
|
80
86
|
}
|
81
87
|
|
data/src/WebPage.h
CHANGED
@@ -15,6 +15,7 @@ class WebPage : public QWebPage {
|
|
15
15
|
void loadStarted();
|
16
16
|
void loadFinished(bool);
|
17
17
|
bool isLoading() const;
|
18
|
+
void frameCreated(QWebFrame *);
|
18
19
|
|
19
20
|
protected:
|
20
21
|
virtual void javaScriptConsoleMessage(const QString &message, int lineNumber, const QString &sourceID);
|
data/src/find_command.h
CHANGED
data/src/webkit_server.pro
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
TEMPLATE = app
|
2
2
|
TARGET = webkit_server
|
3
3
|
DESTDIR = .
|
4
|
-
HEADERS = WebPage.h Server.h Connection.h Command.h Visit.h Find.h Reset.h Node.h JavascriptInvocation.h Url.h Source.h Evaluate.h Execute.h
|
5
|
-
SOURCES = main.cpp WebPage.cpp Server.cpp Connection.cpp Command.cpp Visit.cpp Find.cpp Reset.cpp Node.cpp JavascriptInvocation.cpp Url.cpp Source.cpp Evaluate.cpp Execute.cpp
|
4
|
+
HEADERS = WebPage.h Server.h Connection.h Command.h Visit.h Find.h Reset.h Node.h JavascriptInvocation.h Url.h Source.h Evaluate.h Execute.h FrameFocus.h
|
5
|
+
SOURCES = main.cpp WebPage.cpp Server.cpp Connection.cpp Command.cpp Visit.cpp Find.cpp Reset.cpp Node.cpp JavascriptInvocation.cpp Url.cpp Source.cpp Evaluate.cpp Execute.cpp FrameFocus.cpp
|
6
6
|
RESOURCES = webkit_server.qrc
|
7
7
|
QT += network webkit
|
8
8
|
CONFIG += console
|
metadata
CHANGED
@@ -1,32 +1,45 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capybara-webkit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 23
|
4
5
|
prerelease:
|
5
|
-
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 0.2.0
|
6
11
|
platform: ruby
|
7
12
|
authors:
|
8
13
|
- thoughtbot
|
9
14
|
- Joe Ferris
|
10
15
|
- Jason Morrison
|
11
16
|
- Tristan Dunn
|
17
|
+
- Joshua Clayton
|
18
|
+
- Yuichi Tateno
|
19
|
+
- Aaron Gibralter
|
12
20
|
autorequire:
|
13
21
|
bindir: bin
|
14
22
|
cert_chain: []
|
15
23
|
|
16
|
-
date: 2011-04-
|
24
|
+
date: 2011-04-20 00:00:00 -04:00
|
17
25
|
default_executable:
|
18
26
|
dependencies:
|
19
27
|
- !ruby/object:Gem::Dependency
|
20
|
-
|
28
|
+
type: :runtime
|
21
29
|
requirement: &id001 !ruby/object:Gem::Requirement
|
22
30
|
none: false
|
23
31
|
requirements:
|
24
32
|
- - ~>
|
25
33
|
- !ruby/object:Gem::Version
|
34
|
+
hash: 13
|
35
|
+
segments:
|
36
|
+
- 0
|
37
|
+
- 4
|
38
|
+
- 1
|
26
39
|
version: 0.4.1
|
27
|
-
type: :runtime
|
28
|
-
prerelease: false
|
29
40
|
version_requirements: *id001
|
41
|
+
name: capybara
|
42
|
+
prerelease: false
|
30
43
|
description:
|
31
44
|
email: support@thoughtbot.com
|
32
45
|
executables: []
|
@@ -65,6 +78,8 @@ files:
|
|
65
78
|
- src/Execute.h
|
66
79
|
- src/Find.cpp
|
67
80
|
- src/Find.h
|
81
|
+
- src/FrameFocus.cpp
|
82
|
+
- src/FrameFocus.h
|
68
83
|
- src/JavascriptInvocation.cpp
|
69
84
|
- src/JavascriptInvocation.h
|
70
85
|
- src/Node.cpp
|
@@ -103,7 +118,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
103
118
|
requirements:
|
104
119
|
- - ">="
|
105
120
|
- !ruby/object:Gem::Version
|
106
|
-
hash:
|
121
|
+
hash: 3
|
107
122
|
segments:
|
108
123
|
- 0
|
109
124
|
version: "0"
|
@@ -112,11 +127,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
112
127
|
requirements:
|
113
128
|
- - ">="
|
114
129
|
- !ruby/object:Gem::Version
|
130
|
+
hash: 3
|
131
|
+
segments:
|
132
|
+
- 0
|
115
133
|
version: "0"
|
116
134
|
requirements: []
|
117
135
|
|
118
136
|
rubyforge_project:
|
119
|
-
rubygems_version: 1.6.
|
137
|
+
rubygems_version: 1.6.1
|
120
138
|
signing_key:
|
121
139
|
specification_version: 3
|
122
140
|
summary: Headless Webkit driver for Capybara
|