otherinbox-capybara-webkit 0.12.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/.gitignore +19 -0
- data/.rspec +2 -0
- data/Appraisals +7 -0
- data/CONTRIBUTING.md +47 -0
- data/ChangeLog +70 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +68 -0
- data/LICENSE +19 -0
- data/NEWS.md +36 -0
- data/README.md +114 -0
- data/Rakefile +65 -0
- data/bin/Info.plist +22 -0
- data/capybara-webkit.gemspec +28 -0
- data/extconf.rb +2 -0
- data/gemfiles/1.0.gemfile +7 -0
- data/gemfiles/1.0.gemfile.lock +70 -0
- data/gemfiles/1.1.gemfile +7 -0
- data/gemfiles/1.1.gemfile.lock +70 -0
- data/lib/capybara-webkit.rb +1 -0
- data/lib/capybara/driver/webkit.rb +135 -0
- data/lib/capybara/driver/webkit/browser.rb +168 -0
- data/lib/capybara/driver/webkit/connection.rb +120 -0
- data/lib/capybara/driver/webkit/cookie_jar.rb +55 -0
- data/lib/capybara/driver/webkit/node.rb +118 -0
- data/lib/capybara/driver/webkit/socket_debugger.rb +43 -0
- data/lib/capybara/driver/webkit/version.rb +7 -0
- data/lib/capybara/webkit.rb +11 -0
- data/lib/capybara/webkit/matchers.rb +37 -0
- data/lib/capybara_webkit_builder.rb +68 -0
- data/spec/browser_spec.rb +248 -0
- data/spec/capybara_webkit_builder_spec.rb +37 -0
- data/spec/connection_spec.rb +54 -0
- data/spec/cookie_jar_spec.rb +48 -0
- data/spec/driver_rendering_spec.rb +80 -0
- data/spec/driver_resize_window_spec.rb +59 -0
- data/spec/driver_spec.rb +1552 -0
- data/spec/integration/driver_spec.rb +20 -0
- data/spec/integration/session_spec.rb +137 -0
- data/spec/self_signed_ssl_cert.rb +42 -0
- data/spec/spec_helper.rb +46 -0
- data/src/Body.h +12 -0
- data/src/ClearCookies.cpp +15 -0
- data/src/ClearCookies.h +11 -0
- data/src/Command.cpp +19 -0
- data/src/Command.h +31 -0
- data/src/CommandFactory.cpp +38 -0
- data/src/CommandFactory.h +16 -0
- data/src/CommandParser.cpp +76 -0
- data/src/CommandParser.h +33 -0
- data/src/Connection.cpp +71 -0
- data/src/Connection.h +37 -0
- data/src/ConsoleMessages.cpp +10 -0
- data/src/ConsoleMessages.h +12 -0
- data/src/CurrentUrl.cpp +68 -0
- data/src/CurrentUrl.h +16 -0
- data/src/Evaluate.cpp +84 -0
- data/src/Evaluate.h +22 -0
- data/src/Execute.cpp +16 -0
- data/src/Execute.h +12 -0
- data/src/Find.cpp +19 -0
- data/src/Find.h +13 -0
- data/src/FrameFocus.cpp +66 -0
- data/src/FrameFocus.h +28 -0
- data/src/GetCookies.cpp +20 -0
- data/src/GetCookies.h +14 -0
- data/src/Header.cpp +18 -0
- data/src/Header.h +11 -0
- data/src/Headers.cpp +10 -0
- data/src/Headers.h +12 -0
- data/src/IgnoreSslErrors.cpp +12 -0
- data/src/IgnoreSslErrors.h +12 -0
- data/src/JavascriptInvocation.cpp +14 -0
- data/src/JavascriptInvocation.h +19 -0
- data/src/NetworkAccessManager.cpp +29 -0
- data/src/NetworkAccessManager.h +19 -0
- data/src/NetworkCookieJar.cpp +101 -0
- data/src/NetworkCookieJar.h +15 -0
- data/src/Node.cpp +14 -0
- data/src/Node.h +13 -0
- data/src/NullCommand.cpp +10 -0
- data/src/NullCommand.h +11 -0
- data/src/PageLoadingCommand.cpp +46 -0
- data/src/PageLoadingCommand.h +40 -0
- data/src/Render.cpp +18 -0
- data/src/Render.h +12 -0
- data/src/RequestedUrl.cpp +12 -0
- data/src/RequestedUrl.h +12 -0
- data/src/Reset.cpp +29 -0
- data/src/Reset.h +15 -0
- data/src/ResizeWindow.cpp +16 -0
- data/src/ResizeWindow.h +12 -0
- data/src/Response.cpp +24 -0
- data/src/Response.h +15 -0
- data/src/Server.cpp +24 -0
- data/src/Server.h +21 -0
- data/src/SetCookie.cpp +16 -0
- data/src/SetCookie.h +11 -0
- data/src/SetProxy.cpp +22 -0
- data/src/SetProxy.h +11 -0
- data/src/SetSkipImageLoading.cpp +11 -0
- data/src/SetSkipImageLoading.h +11 -0
- data/src/Source.cpp +18 -0
- data/src/Source.h +19 -0
- data/src/Status.cpp +12 -0
- data/src/Status.h +12 -0
- data/src/UnsupportedContentHandler.cpp +32 -0
- data/src/UnsupportedContentHandler.h +18 -0
- data/src/Url.cpp +12 -0
- data/src/Url.h +12 -0
- data/src/Visit.cpp +12 -0
- data/src/Visit.h +12 -0
- data/src/WebPage.cpp +246 -0
- data/src/WebPage.h +58 -0
- data/src/body.cpp +10 -0
- data/src/capybara.js +315 -0
- data/src/find_command.h +30 -0
- data/src/main.cpp +31 -0
- data/src/webkit_server.pro +87 -0
- data/src/webkit_server.qrc +5 -0
- data/templates/Command.cpp +10 -0
- data/templates/Command.h +12 -0
- data/webkit_server.pro +4 -0
- metadata +300 -0
data/src/CommandParser.h
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#include <QObject>
|
|
2
|
+
#include <QStringList>
|
|
3
|
+
|
|
4
|
+
class QIODevice;
|
|
5
|
+
class CommandFactory;
|
|
6
|
+
class Command;
|
|
7
|
+
|
|
8
|
+
class CommandParser : public QObject {
|
|
9
|
+
Q_OBJECT
|
|
10
|
+
|
|
11
|
+
public:
|
|
12
|
+
CommandParser(QIODevice *device, CommandFactory *commandFactory, QObject *parent = 0);
|
|
13
|
+
|
|
14
|
+
public slots:
|
|
15
|
+
void checkNext();
|
|
16
|
+
|
|
17
|
+
signals:
|
|
18
|
+
void commandReady(Command *command);
|
|
19
|
+
|
|
20
|
+
private:
|
|
21
|
+
void readLine();
|
|
22
|
+
void readDataBlock();
|
|
23
|
+
void processNext(const char *line);
|
|
24
|
+
void processArgument(const char *data);
|
|
25
|
+
void reset();
|
|
26
|
+
QIODevice *m_device;
|
|
27
|
+
QString m_commandName;
|
|
28
|
+
QStringList m_arguments;
|
|
29
|
+
int m_argumentsExpected;
|
|
30
|
+
int m_expectingDataSize;
|
|
31
|
+
CommandFactory *m_commandFactory;
|
|
32
|
+
};
|
|
33
|
+
|
data/src/Connection.cpp
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
#include "Connection.h"
|
|
2
|
+
#include "WebPage.h"
|
|
3
|
+
#include "CommandParser.h"
|
|
4
|
+
#include "CommandFactory.h"
|
|
5
|
+
#include "PageLoadingCommand.h"
|
|
6
|
+
#include "Command.h"
|
|
7
|
+
|
|
8
|
+
#include <QTcpSocket>
|
|
9
|
+
|
|
10
|
+
Connection::Connection(QTcpSocket *socket, WebPage *page, QObject *parent) :
|
|
11
|
+
QObject(parent) {
|
|
12
|
+
m_socket = socket;
|
|
13
|
+
m_page = page;
|
|
14
|
+
m_commandFactory = new CommandFactory(page, this);
|
|
15
|
+
m_commandParser = new CommandParser(socket, m_commandFactory, this);
|
|
16
|
+
m_pageSuccess = true;
|
|
17
|
+
m_commandWaiting = false;
|
|
18
|
+
connect(m_socket, SIGNAL(readyRead()), m_commandParser, SLOT(checkNext()));
|
|
19
|
+
connect(m_commandParser, SIGNAL(commandReady(Command *)), this, SLOT(commandReady(Command *)));
|
|
20
|
+
connect(m_page, SIGNAL(pageFinished(bool)), this, SLOT(pendingLoadFinished(bool)));
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
void Connection::commandReady(Command *command) {
|
|
24
|
+
m_queuedCommand = command;
|
|
25
|
+
if (m_page->isLoading())
|
|
26
|
+
m_commandWaiting = true;
|
|
27
|
+
else
|
|
28
|
+
startCommand();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
void Connection::startCommand() {
|
|
32
|
+
m_commandWaiting = false;
|
|
33
|
+
if (m_pageSuccess) {
|
|
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();
|
|
37
|
+
} else {
|
|
38
|
+
writePageLoadFailure();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
void Connection::pendingLoadFinished(bool success) {
|
|
43
|
+
m_pageSuccess = success;
|
|
44
|
+
if (m_commandWaiting)
|
|
45
|
+
startCommand();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
void Connection::writePageLoadFailure() {
|
|
49
|
+
m_pageSuccess = true;
|
|
50
|
+
QString message = m_page->failureString();
|
|
51
|
+
writeResponse(new Response(false, message));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
void Connection::finishCommand(Response *response) {
|
|
55
|
+
m_runningCommand->deleteLater();
|
|
56
|
+
writeResponse(response);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
void Connection::writeResponse(Response *response) {
|
|
60
|
+
if (response->isSuccess())
|
|
61
|
+
m_socket->write("ok\n");
|
|
62
|
+
else
|
|
63
|
+
m_socket->write("failure\n");
|
|
64
|
+
|
|
65
|
+
QByteArray messageUtf8 = response->message();
|
|
66
|
+
QString messageLength = QString::number(messageUtf8.size()) + "\n";
|
|
67
|
+
m_socket->write(messageLength.toAscii());
|
|
68
|
+
m_socket->write(messageUtf8);
|
|
69
|
+
delete response;
|
|
70
|
+
}
|
|
71
|
+
|
data/src/Connection.h
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#include <QObject>
|
|
2
|
+
#include <QStringList>
|
|
3
|
+
|
|
4
|
+
class QTcpSocket;
|
|
5
|
+
class WebPage;
|
|
6
|
+
class Command;
|
|
7
|
+
class Response;
|
|
8
|
+
class CommandParser;
|
|
9
|
+
class CommandFactory;
|
|
10
|
+
class PageLoadingCommand;
|
|
11
|
+
|
|
12
|
+
class Connection : public QObject {
|
|
13
|
+
Q_OBJECT
|
|
14
|
+
|
|
15
|
+
public:
|
|
16
|
+
Connection(QTcpSocket *socket, WebPage *page, QObject *parent = 0);
|
|
17
|
+
|
|
18
|
+
public slots:
|
|
19
|
+
void commandReady(Command *command);
|
|
20
|
+
void finishCommand(Response *response);
|
|
21
|
+
void pendingLoadFinished(bool success);
|
|
22
|
+
|
|
23
|
+
private:
|
|
24
|
+
void startCommand();
|
|
25
|
+
void writeResponse(Response *response);
|
|
26
|
+
void writePageLoadFailure();
|
|
27
|
+
|
|
28
|
+
QTcpSocket *m_socket;
|
|
29
|
+
Command *m_queuedCommand;
|
|
30
|
+
WebPage *m_page;
|
|
31
|
+
CommandParser *m_commandParser;
|
|
32
|
+
CommandFactory *m_commandFactory;
|
|
33
|
+
PageLoadingCommand *m_runningCommand;
|
|
34
|
+
bool m_pageSuccess;
|
|
35
|
+
bool m_commandWaiting;
|
|
36
|
+
};
|
|
37
|
+
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#include "ConsoleMessages.h"
|
|
2
|
+
#include "WebPage.h"
|
|
3
|
+
|
|
4
|
+
ConsoleMessages::ConsoleMessages(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
void ConsoleMessages::start() {
|
|
8
|
+
emit finished(new Response(true, page()->consoleMessages()));
|
|
9
|
+
}
|
|
10
|
+
|
data/src/CurrentUrl.cpp
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#include "CurrentUrl.h"
|
|
2
|
+
#include "WebPage.h"
|
|
3
|
+
|
|
4
|
+
CurrentUrl::CurrentUrl(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/*
|
|
8
|
+
* This CurrentUrl command attempts to produce a current_url value consistent
|
|
9
|
+
* with that returned by the Selenium WebDriver Capybara driver.
|
|
10
|
+
*
|
|
11
|
+
* It does not currently return the correct value in the case of an iframe whose
|
|
12
|
+
* source URL results in a redirect because the loading of the iframe does not
|
|
13
|
+
* generate a history item. This is most likely a rare case and is consistent
|
|
14
|
+
* with the current behavior of the capybara-webkit driver.
|
|
15
|
+
*
|
|
16
|
+
* The following two values are *not* affected by Javascript pushState.
|
|
17
|
+
*
|
|
18
|
+
* QWebFrame->url()
|
|
19
|
+
* QWebHistoryItem.originalUrl()
|
|
20
|
+
*
|
|
21
|
+
* The following two values *are* affected by Javascript pushState.
|
|
22
|
+
*
|
|
23
|
+
* QWebFrame->requestedUrl()
|
|
24
|
+
* QWebHistoryItem.url()
|
|
25
|
+
*
|
|
26
|
+
* In the cases that we have access to both the QWebFrame values and the
|
|
27
|
+
* correct history item for that frame, we can compare the values and determine
|
|
28
|
+
* if a redirect occurred and if pushState was used. The table below describes
|
|
29
|
+
* the various combinations of URL values that are possible.
|
|
30
|
+
*
|
|
31
|
+
* O -> originally requested URL
|
|
32
|
+
* R -> URL after redirection
|
|
33
|
+
* P -> URL set by pushState
|
|
34
|
+
* * -> denotes the desired URL value from the frame
|
|
35
|
+
*
|
|
36
|
+
* frame history
|
|
37
|
+
* case url requestedUrl url originalUrl
|
|
38
|
+
* -----------------------------------------------------------------
|
|
39
|
+
* regular load O O* O O
|
|
40
|
+
*
|
|
41
|
+
* redirect w/o R* O R O
|
|
42
|
+
* pushState
|
|
43
|
+
*
|
|
44
|
+
* pushState O P* P O
|
|
45
|
+
* only
|
|
46
|
+
*
|
|
47
|
+
* redirect w/ R P* P O
|
|
48
|
+
* pushState
|
|
49
|
+
*
|
|
50
|
+
* Based on the above information, we only need to check for the case of a
|
|
51
|
+
* redirect w/o pushState, in which case QWebFrame->url() will have the correct
|
|
52
|
+
* current_url value. In all other cases QWebFrame->requestedUrl() is correct.
|
|
53
|
+
*/
|
|
54
|
+
void CurrentUrl::start() {
|
|
55
|
+
QUrl humanUrl = wasRedirectedAndNotModifiedByJavascript() ?
|
|
56
|
+
page()->currentFrame()->url() : page()->currentFrame()->requestedUrl();
|
|
57
|
+
QByteArray encodedBytes = humanUrl.toEncoded();
|
|
58
|
+
emit finished(new Response(true, encodedBytes));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
bool CurrentUrl::wasRegularLoad() {
|
|
62
|
+
return page()->currentFrame()->url() == page()->currentFrame()->requestedUrl();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
bool CurrentUrl::wasRedirectedAndNotModifiedByJavascript() {
|
|
66
|
+
return !wasRegularLoad() && page()->currentFrame()->url() == page()->history()->currentItem().url();
|
|
67
|
+
}
|
|
68
|
+
|
data/src/CurrentUrl.h
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#include "Command.h"
|
|
2
|
+
|
|
3
|
+
class WebPage;
|
|
4
|
+
|
|
5
|
+
class CurrentUrl : public Command {
|
|
6
|
+
Q_OBJECT
|
|
7
|
+
|
|
8
|
+
public:
|
|
9
|
+
CurrentUrl(WebPage *page, QStringList &arguments, QObject *parent = 0);
|
|
10
|
+
virtual void start();
|
|
11
|
+
|
|
12
|
+
private:
|
|
13
|
+
bool wasRegularLoad();
|
|
14
|
+
bool wasRedirectedAndNotModifiedByJavascript();
|
|
15
|
+
};
|
|
16
|
+
|
data/src/Evaluate.cpp
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
#include "Evaluate.h"
|
|
2
|
+
#include "WebPage.h"
|
|
3
|
+
#include <iostream>
|
|
4
|
+
|
|
5
|
+
Evaluate::Evaluate(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
|
|
6
|
+
m_buffer = "";
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
void Evaluate::start() {
|
|
10
|
+
QVariant result = page()->currentFrame()->evaluateJavaScript(arguments()[0]);
|
|
11
|
+
addVariant(result);
|
|
12
|
+
emit finished(new Response(true, m_buffer));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
void Evaluate::addVariant(QVariant &object) {
|
|
16
|
+
if (object.isValid()) {
|
|
17
|
+
switch(object.type()) {
|
|
18
|
+
case QMetaType::QString:
|
|
19
|
+
{
|
|
20
|
+
QString string = object.toString();
|
|
21
|
+
addString(string);
|
|
22
|
+
}
|
|
23
|
+
break;
|
|
24
|
+
case QMetaType::QVariantList:
|
|
25
|
+
{
|
|
26
|
+
QVariantList list = object.toList();
|
|
27
|
+
addArray(list);
|
|
28
|
+
}
|
|
29
|
+
break;
|
|
30
|
+
case QMetaType::Double:
|
|
31
|
+
m_buffer.append(object.toString());
|
|
32
|
+
break;
|
|
33
|
+
case QMetaType::QVariantMap:
|
|
34
|
+
{
|
|
35
|
+
QVariantMap map = object.toMap();
|
|
36
|
+
addMap(map);
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
case QMetaType::Bool:
|
|
40
|
+
{
|
|
41
|
+
m_buffer.append(object.toString());
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
default:
|
|
45
|
+
m_buffer.append("null");
|
|
46
|
+
}
|
|
47
|
+
} else {
|
|
48
|
+
m_buffer.append("null");
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
void Evaluate::addString(QString &string) {
|
|
53
|
+
QString escapedString(string);
|
|
54
|
+
escapedString.replace("\"", "\\\"");
|
|
55
|
+
m_buffer.append("\"");
|
|
56
|
+
m_buffer.append(escapedString);
|
|
57
|
+
m_buffer.append("\"");
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
void Evaluate::addArray(QVariantList &list) {
|
|
61
|
+
m_buffer.append("[");
|
|
62
|
+
for (int i = 0; i < list.length(); i++) {
|
|
63
|
+
if (i > 0)
|
|
64
|
+
m_buffer.append(",");
|
|
65
|
+
addVariant(list[i]);
|
|
66
|
+
}
|
|
67
|
+
m_buffer.append("]");
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
void Evaluate::addMap(QVariantMap &map) {
|
|
71
|
+
m_buffer.append("{");
|
|
72
|
+
QMapIterator<QString, QVariant> iterator(map);
|
|
73
|
+
while (iterator.hasNext()) {
|
|
74
|
+
iterator.next();
|
|
75
|
+
QString key = iterator.key();
|
|
76
|
+
QVariant value = iterator.value();
|
|
77
|
+
addString(key);
|
|
78
|
+
m_buffer.append(":");
|
|
79
|
+
addVariant(value);
|
|
80
|
+
if (iterator.hasNext())
|
|
81
|
+
m_buffer.append(",");
|
|
82
|
+
}
|
|
83
|
+
m_buffer.append("}");
|
|
84
|
+
}
|
data/src/Evaluate.h
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#include "Command.h"
|
|
2
|
+
|
|
3
|
+
#include <QVariantList>
|
|
4
|
+
|
|
5
|
+
class WebPage;
|
|
6
|
+
|
|
7
|
+
class Evaluate : public Command {
|
|
8
|
+
Q_OBJECT
|
|
9
|
+
|
|
10
|
+
public:
|
|
11
|
+
Evaluate(WebPage *page, QStringList &arguments, QObject *parent = 0);
|
|
12
|
+
virtual void start();
|
|
13
|
+
|
|
14
|
+
private:
|
|
15
|
+
void addVariant(QVariant &object);
|
|
16
|
+
void addString(QString &string);
|
|
17
|
+
void addArray(QVariantList &list);
|
|
18
|
+
void addMap(QVariantMap &map);
|
|
19
|
+
|
|
20
|
+
QString m_buffer;
|
|
21
|
+
};
|
|
22
|
+
|
data/src/Execute.cpp
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#include "Execute.h"
|
|
2
|
+
#include "WebPage.h"
|
|
3
|
+
|
|
4
|
+
Execute::Execute(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
void Execute::start() {
|
|
8
|
+
QString script = arguments()[0] + QString("; 'success'");
|
|
9
|
+
QVariant result = page()->currentFrame()->evaluateJavaScript(script);
|
|
10
|
+
if (result.isValid()) {
|
|
11
|
+
emit finished(new Response(true));
|
|
12
|
+
} else {
|
|
13
|
+
emit finished(new Response(false, QString("Javascript failed to execute")));
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
data/src/Execute.h
ADDED
data/src/Find.cpp
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#include "Find.h"
|
|
2
|
+
#include "Command.h"
|
|
3
|
+
#include "WebPage.h"
|
|
4
|
+
|
|
5
|
+
Find::Find(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
void Find::start() {
|
|
9
|
+
QString message;
|
|
10
|
+
QVariant result = page()->invokeCapybaraFunction("find", arguments());
|
|
11
|
+
|
|
12
|
+
if (result.isValid()) {
|
|
13
|
+
message = result.toString();
|
|
14
|
+
emit finished(new Response(true, message));
|
|
15
|
+
} else {
|
|
16
|
+
emit finished(new Response(false, QString("Invalid XPath expression")));
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
data/src/Find.h
ADDED
data/src/FrameFocus.cpp
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
#include "FrameFocus.h"
|
|
2
|
+
#include "Command.h"
|
|
3
|
+
#include "WebPage.h"
|
|
4
|
+
|
|
5
|
+
FrameFocus::FrameFocus(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
void FrameFocus::start() {
|
|
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
|
+
emit finished(new Response(false, QString("Already at parent frame.")));
|
|
54
|
+
} else {
|
|
55
|
+
page()->currentFrame()->parentFrame()->setFocus();
|
|
56
|
+
success();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
void FrameFocus::frameNotFound() {
|
|
61
|
+
emit finished(new Response(false, QString("Unable to locate frame. ")));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
void FrameFocus::success() {
|
|
65
|
+
emit finished(new Response(true));
|
|
66
|
+
}
|