Permalink
Browse files

Merge pull request #319 from detro/ghostdriver-dev

GhostDriver Development Branch - Master Push #4
  • Loading branch information...
2 parents 64fa65e + 2658374 commit 9a25f31715e15c9497be35e8213e11ede3e9bc7d @ariya committed Sep 19, 2012
Showing with 361 additions and 130 deletions.
  1. +1 −0 .gitignore
  2. +1 −1 examples/pagecallback.coffee
  3. +193 −89 src/cookiejar.cpp
  4. +11 −8 src/cookiejar.h
  5. +6 −7 src/main.cpp
  6. +40 −0 src/phantom.cpp
  7. +51 −0 src/phantom.h
  8. +23 −17 src/webpage.cpp
  9. +8 −4 src/webpage.h
  10. +6 −0 src/webserver.cpp
  11. +21 −4 test/webpage-spec.js
View
@@ -19,6 +19,7 @@ debian/*/
/deploy/qt-*.tar.gz
/deploy/Qt-*
/symbols
+src/qt/qtc-debugging-helper
# ignore ctags
/tags
@@ -7,7 +7,7 @@ p.onCallback = (msg) ->
"Hello there, I'm coming to you from the 'phantom' context instead"
p.evaluate ->
- callbackResponse = phantomCallback("Hello, I'm coming to you from the 'page' context")
+ callbackResponse = callPhantom("Hello, I'm coming to you from the 'page' context")
console.log "Received by the 'page' context: " + callbackResponse
phantom.exit()
View

Large diffs are not rendered by default.

Oops, something went wrong.
View
@@ -50,30 +50,33 @@ class CookieJar: public QNetworkCookieJar
bool setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl & url);
QList<QNetworkCookie> cookiesForUrl (const QUrl & url) const;
- void addCookie(const QNetworkCookie &cookie, const QString &url = QString());
- void addCookieFromMap(const QVariantMap &cookie, const QString &url = QString());
- void addCookies(const QList<QNetworkCookie> &cookiesList, const QString &url = QString());
- void addCookiesFromMap(const QVariantList &cookiesList, const QString &url = QString());
+ bool addCookie(const QNetworkCookie &cookie, const QString &url = QString());
+ bool addCookieFromMap(const QVariantMap &cookie, const QString &url = QString());
+ bool addCookies(const QList<QNetworkCookie> &cookiesList, const QString &url = QString());
+ bool addCookiesFromMap(const QVariantList &cookiesList, const QString &url = QString());
QList<QNetworkCookie> cookies(const QString &url = QString()) const;
QVariantList cookiesToMap(const QString &url = QString()) const;
QNetworkCookie cookie(const QString &name, const QString &url = QString()) const;
QVariantMap cookieToMap(const QString &name, const QString &url = QString()) const;
- void deleteCookie(const QString &name, const QString &url = QString());
- void deleteCookies(const QString &url = QString());
+ bool deleteCookie(const QString &name, const QString &url = QString());
+ bool deleteCookies(const QString &url = QString());
void clearCookies();
void enable();
void disable();
bool isEnabled() const;
private slots:
- void save();
- void load();
bool purgeExpiredCookies();
bool purgeSessionCookies();
+ void save();
+ void load();
+
+private:
+ bool contains(const QNetworkCookie &cookie) const;
private:
QSettings *m_cookieStorage;
View
@@ -77,17 +77,17 @@ int main(int argc, char** argv, const char** envp)
if (cbBuffer == 0) {
eh = new ExceptionHandler(TEXT("."), NULL, Utils::exceptionHandler, NULL, ExceptionHandler::HANDLER_ALL);
- } else {
+ } else {
LPWSTR szBuffer = reinterpret_cast<LPWSTR>(malloc(sizeof(TCHAR) * (cbBuffer + 1)));
-
+
if (ExpandEnvironmentStrings(TEXT("%TEMP%"), szBuffer, cbBuffer + 1) > 0) {
wstring lpDumpPath(szBuffer);
eh = new ExceptionHandler(lpDumpPath, NULL, Utils::exceptionHandler, NULL, ExceptionHandler::HANDLER_ALL);
}
free(szBuffer);
}
#endif
-
+
QApplication app(argc, argv);
app.setWindowIcon(QIcon(":/phantomjs-icon.png"));
@@ -99,13 +99,12 @@ int main(int argc, char** argv, const char** envp)
// Prepare the "env" singleton using the environment variables
Env::instance()->parse(envp);
- // Get the Phantom singleton
- Phantom *phantom = Phantom::instance();
-
// Registering an alternative Message Handler
- Utils::printDebugMessages = phantom->printDebugMessages();
qInstallMsgHandler(Utils::messageHandler);
+ // Get the Phantom singleton
+ Phantom *phantom = Phantom::instance();
+
// Start script execution
if (phantom->execute()) {
app.exec();
View
@@ -63,6 +63,8 @@ Phantom::Phantom(QObject *parent)
// Prepare the configuration object based on the command line arguments.
// Because this object will be used by other classes, it needs to be ready ASAP.
m_config.init(&args);
+ // Apply debug configuration as early as possible
+ Utils::printDebugMessages = m_config.printDebugMessages();
// initialize key map
QMetaEnum keys = staticQtMetaObject.enumerator( staticQtMetaObject.indexOfEnumerator("Key") );
@@ -378,6 +380,39 @@ void Phantom::onInitialized()
);
}
+bool Phantom::setCookies(const QVariantList &cookies)
+{
+ // Delete all the cookies from the CookieJar
+ CookieJar::instance()->clearCookies();
+ // Add a new set of cookies
+ return CookieJar::instance()->addCookiesFromMap(cookies);
+}
+
+QVariantList Phantom::cookies() const
+{
+ // Return all the Cookies in the CookieJar, as a list of Maps (aka JSON in JS space)
+ return CookieJar::instance()->cookiesToMap();
+}
+
+bool Phantom::addCookie(const QVariantMap &cookie)
+{
+ return CookieJar::instance()->addCookieFromMap(cookie);
+}
+
+bool Phantom::deleteCookie(const QString &cookieName)
+{
+ if (!cookieName.isEmpty()) {
+ return CookieJar::instance()->deleteCookie(cookieName);
+ }
+ return false;
+}
+
+void Phantom::clearCookies()
+{
+ CookieJar::instance()->clearCookies();
+}
+
+
// private:
void Phantom::doExit(int code)
{
@@ -407,7 +442,12 @@ void Phantom::initCompletions()
addCompletion("version");
addCompletion("keys");
addCompletion("cookiesEnabled");
+ addCompletion("cookies");
// functions
addCompletion("exit");
+ addCompletion("debugExit");
addCompletion("injectJs");
+ addCompletion("addCookie");
+ addCompletion("deleteCookie");
+ addCompletion("clearCookies");
}
View
@@ -56,6 +56,7 @@ class Phantom: public REPLCompletable
Q_PROPERTY(QObject *page READ page)
Q_PROPERTY(QVariantMap keys READ keys)
Q_PROPERTY(bool cookiesEnabled READ areCookiesEnabled WRITE setCookiesEnabled)
+ Q_PROPERTY(QVariantList cookies READ cookies WRITE setCookies)
private:
// Private constructor: the Phantom class is a singleton
@@ -110,6 +111,56 @@ public slots:
void loadModule(const QString &moduleSource, const QString &filename);
bool injectJs(const QString &jsFilePath);
+ /**
+ * Allows to set cookies into the CookieJar.
+ * Pages will be able to access only the cookies they are supposed to see given their URL.
+ *
+ * Cookies are expected in the format:
+ * <pre>
+ * {
+ * "name" : "cookie name (string)",
+ * "value" : "cookie value (string)",
+ * "domain" : "cookie domain (string)",
+ * "path" : "cookie path (string, optional)",
+ * "httponly" : "http only cookie (boolean, optional)",
+ * "secure" : "secure cookie (boolean, optional)",
+ * "expires" : "expiration date (string, GMT format, optional)"
+ * }
+ * </pre>
+ * @brief setCookies
+ * @param cookies Expects a QList of QVariantMaps
+ * @return Boolean "true" if at least 1 cookie was set
+ */
+ bool setCookies(const QVariantList &cookies);
+ /**
+ * All the Cookies in the CookieJar
+ *
+ * @see WebPage::setCookies for details on the format
+ * @brief cookies
+ * @return QList of QVariantMap cookies visible to this Page, at the current URL.
+ */
+ QVariantList cookies() const;
+ /**
+ * Add a Cookie (in QVariantMap format) into the CookieJar
+ * @see WebPage::setCookies for details on the format
+ * @brief addCookie
+ * @param cookie Cookie in QVariantMap format
+ * @return Boolean "true" if cookie was added
+ */
+ bool addCookie(const QVariantMap &cookie);
+ /**
+ * Delete cookie by name from the CookieJar
+ * @brief deleteCookie
+ * @param cookieName Name of the Cookie to delete
+ * @return Boolean "true" if cookie was deleted
+ */
+ bool deleteCookie(const QString &cookieName);
+ /**
+ * Delete All Cookies from the CookieJar
+ * @brief clearCookies
+ */
+ void clearCookies();
+
// exit() will not exit in debug mode. debugExit() will always exit.
void exit(int code = 0);
void debugExit(int code = 0);
View
@@ -563,12 +563,12 @@ QVariantMap WebPage::customHeaders() const
return m_networkAccessManager->customHeaders();
}
-void WebPage::setCookies(const QVariantList &cookies)
+bool WebPage::setCookies(const QVariantList &cookies)
{
// Delete all the cookies for this URL
CookieJar::instance()->deleteCookies(this->url());
// Add a new set of cookies foor this URL
- CookieJar::instance()->addCookiesFromMap(cookies, this->url());
+ return CookieJar::instance()->addCookiesFromMap(cookies, this->url());
}
QVariantList WebPage::cookies() const
@@ -577,21 +577,22 @@ QVariantList WebPage::cookies() const
return CookieJar::instance()->cookiesToMap(this->url());
}
-void WebPage::addCookie(const QVariantMap &cookie)
+bool WebPage::addCookie(const QVariantMap &cookie)
{
- CookieJar::instance()->addCookieFromMap(cookie, this->url());
+ return CookieJar::instance()->addCookieFromMap(cookie, this->url());
}
-void WebPage::deleteCookie(const QString &cookieName)
+bool WebPage::deleteCookie(const QString &cookieName)
{
if (!cookieName.isEmpty()) {
- CookieJar::instance()->deleteCookie(cookieName, this->url());
+ return CookieJar::instance()->deleteCookie(cookieName, this->url());
}
+ return false;
}
-void WebPage::clearCookies()
+bool WebPage::clearCookies()
{
- CookieJar::instance()->deleteCookie(this->url());
+ return CookieJar::instance()->deleteCookies(this->url());
}
void WebPage::openUrl(const QString &address, const QVariant &op, const QVariantMap &settings)
@@ -1252,6 +1253,18 @@ QString WebPage::focusedFrameName() const
return m_customWebPage->currentFrame()->frameName();
}
+static void injectCallbacksObjIntoFrames(QWebFrame *frame, WebpageCallbacks *callbacksObject)
+{
+ // Decorate the window object in this frame
+ frame->addToJavaScriptWindowObject(CALLBACKS_OBJECT_NAME, callbacksObject, QScriptEngine::QtOwnership);
+ frame->evaluateJavaScript(CALLBACKS_OBJECT_INJECTION);
+
+ // Decorate the window object in the child frames (recursively)
+ foreach (QWebFrame *childFrame, frame->childFrames()) {
+ injectCallbacksObjIntoFrames(childFrame, callbacksObject);
+ }
+}
+
void WebPage::handleJavaScriptWindowObjectCleared()
{
// Create Callbacks Holder object, if not already present for this page
@@ -1262,15 +1275,8 @@ void WebPage::handleJavaScriptWindowObjectCleared()
// Reset focus on the Main Frame
m_mainFrame->setFocus();
- // Decorate the window object in the Main Frame
- m_mainFrame->addToJavaScriptWindowObject(CALLBACKS_OBJECT_NAME, m_callbacks, QScriptEngine::QtOwnership);
- m_mainFrame->evaluateJavaScript(CALLBACKS_OBJECT_INJECTION);
-
- // Decorate the window object in the Main Frame's Child Frames
- foreach (QWebFrame *childFrame, m_mainFrame->childFrames()) {
- childFrame->addToJavaScriptWindowObject(CALLBACKS_OBJECT_NAME, m_callbacks, QScriptEngine::QtOwnership);
- childFrame->evaluateJavaScript(CALLBACKS_OBJECT_INJECTION);
- }
+ // Inject the Callbacks object in the frame and child-frames (recursively)
+ injectCallbacksObjIntoFrames(m_mainFrame, m_callbacks);
}
void WebPage::initCompletions()
View
@@ -363,8 +363,9 @@ public slots:
* </pre>
* @brief setCookies
* @param cookies Expects a QList of QVariantMaps
+ * @return Boolean "true" if at least 1 cookie was set
*/
- void setCookies(const QVariantList &cookies);
+ bool setCookies(const QVariantList &cookies);
/**
* Cookies visible by this Page, at the current URL.
*
@@ -378,19 +379,22 @@ public slots:
* @see WebPage::setCookies for details on the format
* @brief addCookie
* @param cookie Cookie in QVariantMap format
+ * @return Boolean "true" if cookie was added
*/
- void addCookie(const QVariantMap &cookie);
+ bool addCookie(const QVariantMap &cookie);
/**
* Delete cookie by name from the ones visible by this Page, at the current URL
* @brief deleteCookie
* @param cookieName Name of the Cookie to delete
+ * @return Boolean "true" if cookie was deleted
*/
- void deleteCookie(const QString &cookieName);
+ bool deleteCookie(const QString &cookieName);
/**
* Delete All Cookies visible by this Page, at the current URL
* @brief clearCookies
+ * @return Boolean "true" if cookies were deleted
*/
- void clearCookies();
+ bool clearCookies();
signals:
void initialized();
View
@@ -165,6 +165,11 @@ bool WebServer::handleRequest(mg_event event, mg_connection *conn, const mg_requ
///TODO: encoding?!
+ qDebug() << "HTTP Request - URI" << request->uri;
+ qDebug() << "HTTP Request - Method" << request->request_method;
+ qDebug() << "HTTP Request - HTTP Version" << request->http_version;
+ qDebug() << "HTTP Request - Query String" << request->query_string;
+
if (request->request_method)
requestObject["method"] = QString::fromLocal8Bit(request->request_method);
if (request->http_version)
@@ -384,6 +389,7 @@ void WebServerResponse::writeHead(int statusCode, const QVariantMap &headers)
m_headersSent = true;
m_statusCode = statusCode;
mg_printf(m_conn, "HTTP/1.1 %d %s\r\n", m_statusCode, responseCodeString(m_statusCode));
+ qDebug() << "HTTP Response - Status Code" << m_statusCode << responseCodeString(m_statusCode);
QVariantMap::const_iterator it = headers.constBegin();
while(it != headers.constEnd()) {
qDebug() << "HTTP Response - Sending Header" << it.key() << "=" << it.value().toString();
Oops, something went wrong.

0 comments on commit 9a25f31

Please sign in to comment.