Skip to content
This repository has been archived by the owner on Mar 3, 2020. It is now read-only.

Commit

Permalink
Serialize console messsages using JsonSerializer
Browse files Browse the repository at this point in the history
  • Loading branch information
mhoran committed Jan 3, 2013
1 parent 17158b7 commit ec257f7
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 29 deletions.
8 changes: 2 additions & 6 deletions lib/capybara/webkit/browser.rb
Expand Up @@ -39,12 +39,8 @@ def status_code
end end


def console_messages def console_messages
command("ConsoleMessages").split("\n").map do |messages| JSON.parse(command("ConsoleMessages")).map do |message|
parts = messages.split("|", 3) message.inject({}) { |m,(k,v)| m.merge(k.to_sym => v) }
message = parts.pop.gsub("\\n", "\n")
{ :source => parts.first, :message => message }.tap do |message|
message[:line_number] = Integer(parts[1]) if parts[1]
end
end end
end end


Expand Down
13 changes: 10 additions & 3 deletions spec/driver_spec.rb
@@ -1,3 +1,5 @@
# -*- encoding: UTF-8 -*-

require 'spec_helper' require 'spec_helper'
require 'capybara/webkit/driver' require 'capybara/webkit/driver'
require 'base64' require 'base64'
Expand Down Expand Up @@ -470,12 +472,14 @@ def visit(url, driver=driver)
driver_for_html(<<-HTML) driver_for_html(<<-HTML)
<html> <html>
<head> <head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head> </head>
<body> <body>
<script type="text/javascript"> <script type="text/javascript">
console.log("hello"); console.log("hello");
console.log("hello again"); console.log("hello again");
console.log("hello\\nnewline"); console.log("hello\\nnewline");
console.log("𝄞");
oops oops
</script> </script>
</body> </body>
Expand All @@ -489,9 +493,8 @@ def visit(url, driver=driver)
url = driver_url(driver, "/") url = driver_url(driver, "/")
message = driver.console_messages.first message = driver.console_messages.first
message.should include :source => url, :message => "hello" message.should include :source => url, :message => "hello"
# QtWebKit returns different line numbers depending on the version message[:line_number].should == 6
[5, 6].should include(message[:line_number]) driver.console_messages.length.should eq 5
driver.console_messages.length.should eq 4
end end


it "logs errors to the console" do it "logs errors to the console" do
Expand All @@ -514,6 +517,10 @@ def visit(url, driver=driver)
driver.console_messages.last[:source].should be_nil driver.console_messages.last[:source].should be_nil
driver.console_messages.last[:line_number].should be_nil driver.console_messages.last[:line_number].should be_nil
end end

it "escapes unicode console messages" do
driver.console_messages[3][:message].should == '𝄞'
end
end end


context "javascript dialog interaction" do context "javascript dialog interaction" do
Expand Down
5 changes: 4 additions & 1 deletion src/ConsoleMessages.cpp
@@ -1,11 +1,14 @@
#include "ConsoleMessages.h" #include "ConsoleMessages.h"
#include "WebPage.h" #include "WebPage.h"
#include "WebPageManager.h" #include "WebPageManager.h"
#include "JsonSerializer.h"


ConsoleMessages::ConsoleMessages(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) { ConsoleMessages::ConsoleMessages(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
} }


void ConsoleMessages::start() { void ConsoleMessages::start() {
emitFinished(true, page()->consoleMessages()); JsonSerializer serializer;
QString json = serializer.serialize(page()->consoleMessages());
emitFinished(true, json);
} }


50 changes: 42 additions & 8 deletions src/JsonSerializer.cpp
Expand Up @@ -3,12 +3,12 @@
JsonSerializer::JsonSerializer(QObject *parent) : QObject(parent) { JsonSerializer::JsonSerializer(QObject *parent) : QObject(parent) {
} }


QString JsonSerializer::serialize(QVariant &object) { QString JsonSerializer::serialize(const QVariant &object) {
addVariant(object); addVariant(object);
return m_buffer; return m_buffer;
} }


void JsonSerializer::addVariant(QVariant &object) { void JsonSerializer::addVariant(const QVariant &object) {
if (object.isValid()) { if (object.isValid()) {
switch(object.type()) { switch(object.type()) {
case QMetaType::QString: case QMetaType::QString:
Expand Down Expand Up @@ -37,6 +37,11 @@ void JsonSerializer::addVariant(QVariant &object) {
m_buffer.append(object.toString()); m_buffer.append(object.toString());
break; break;
} }
case QMetaType::Int:
{
m_buffer.append(object.toString());
break;
}
default: default:
m_buffer.append("null"); m_buffer.append("null");
} }
Expand All @@ -45,15 +50,13 @@ void JsonSerializer::addVariant(QVariant &object) {
} }
} }


void JsonSerializer::addString(QString &string) { void JsonSerializer::addString(const QString &string) {
QString escapedString(string);
escapedString.replace("\"", "\\\"");
m_buffer.append("\""); m_buffer.append("\"");
m_buffer.append(escapedString); m_buffer.append(sanitizeString(string));
m_buffer.append("\""); m_buffer.append("\"");
} }


void JsonSerializer::addArray(QVariantList &list) { void JsonSerializer::addArray(const QVariantList &list) {
m_buffer.append("["); m_buffer.append("[");
for (int i = 0; i < list.length(); i++) { for (int i = 0; i < list.length(); i++) {
if (i > 0) if (i > 0)
Expand All @@ -63,7 +66,7 @@ void JsonSerializer::addArray(QVariantList &list) {
m_buffer.append("]"); m_buffer.append("]");
} }


void JsonSerializer::addMap(QVariantMap &map) { void JsonSerializer::addMap(const QVariantMap &map) {
m_buffer.append("{"); m_buffer.append("{");
QMapIterator<QString, QVariant> iterator(map); QMapIterator<QString, QVariant> iterator(map);
while (iterator.hasNext()) { while (iterator.hasNext()) {
Expand All @@ -79,3 +82,34 @@ void JsonSerializer::addMap(QVariantMap &map) {
m_buffer.append("}"); m_buffer.append("}");
} }


QString JsonSerializer::sanitizeString(QString str) {
str.replace("\\", "\\\\");

// escape unicode chars
QString result;
const ushort* unicode = str.utf16();
unsigned int i = 0;

while (unicode[i]) {
if (unicode[i] < 128) {
result.append(unicode[i]);
}
else {
QString hexCode = QString::number(unicode[i], 16).rightJustified(4, '0');

result.append("\\u").append(hexCode);
}
++i;
}
str = result;

str.replace("\"", "\\\"");
str.replace("\b", "\\b");
str.replace("\f", "\\f");
str.replace("\n", "\\n");
str.replace("\r", "\\r");
str.replace("\t", "\\t");

return str;
}

11 changes: 6 additions & 5 deletions src/JsonSerializer.h
Expand Up @@ -6,13 +6,14 @@ class JsonSerializer : public QObject {


public: public:
JsonSerializer(QObject *parent = 0); JsonSerializer(QObject *parent = 0);
QString serialize(QVariant &object); QString serialize(const QVariant &object);


private: private:
void addVariant(QVariant &object); void addVariant(const QVariant &object);
void addString(QString &string); void addString(const QString &string);
void addArray(QVariantList &list); void addArray(const QVariantList &list);
void addMap(QVariantMap &map); void addMap(const QVariantMap &map);
QString sanitizeString(QString string);


QString m_buffer; QString m_buffer;
}; };
Expand Down
13 changes: 9 additions & 4 deletions src/WebPage.cpp
Expand Up @@ -83,8 +83,8 @@ QString WebPage::userAgentForUrl(const QUrl &url ) const {
} }
} }


QString WebPage::consoleMessages() { QVariantList WebPage::consoleMessages() {
return m_consoleMessages.join("\n"); return m_consoleMessages;
} }


QString WebPage::alertMessages() { QString WebPage::alertMessages() {
Expand Down Expand Up @@ -131,10 +131,15 @@ QVariant WebPage::invokeCapybaraFunction(QString &name, const QStringList &argum
} }


void WebPage::javaScriptConsoleMessage(const QString &message, int lineNumber, const QString &sourceID) { void WebPage::javaScriptConsoleMessage(const QString &message, int lineNumber, const QString &sourceID) {
QVariantMap m;
m["message"] = message;
QString fullMessage = QString(message); QString fullMessage = QString(message);
if (!sourceID.isEmpty()) if (!sourceID.isEmpty()) {
fullMessage = sourceID + "|" + QString::number(lineNumber) + "|" + fullMessage; fullMessage = sourceID + "|" + QString::number(lineNumber) + "|" + fullMessage;
m_consoleMessages.append(fullMessage.replace("\n", "\\n")); m["source"] = sourceID;
m["line_number"] = lineNumber;
}
m_consoleMessages.append(m);
m_manager->logger() << qPrintable(fullMessage); m_manager->logger() << qPrintable(fullMessage);
} }


Expand Down
4 changes: 2 additions & 2 deletions src/WebPage.h
Expand Up @@ -23,7 +23,7 @@ class WebPage : public QWebPage {
bool render(const QString &fileName); bool render(const QString &fileName);
virtual bool extension (Extension extension, const ExtensionOption *option=0, ExtensionReturn *output=0); virtual bool extension (Extension extension, const ExtensionOption *option=0, ExtensionReturn *output=0);
void setSkipImageLoading(bool skip); void setSkipImageLoading(bool skip);
QString consoleMessages(); QVariantList consoleMessages();
QString alertMessages(); QString alertMessages();
QString confirmMessages(); QString confirmMessages();
QString promptMessages(); QString promptMessages();
Expand Down Expand Up @@ -71,7 +71,7 @@ class WebPage : public QWebPage {
void setUserStylesheet(); void setUserStylesheet();
bool m_confirm; bool m_confirm;
bool m_prompt; bool m_prompt;
QStringList m_consoleMessages; QVariantList m_consoleMessages;
QStringList m_alertMessages; QStringList m_alertMessages;
QStringList m_confirmMessages; QStringList m_confirmMessages;
QString m_prompt_text; QString m_prompt_text;
Expand Down

0 comments on commit ec257f7

Please sign in to comment.