Skip to content

Commit a9a209d

Browse files
committed
add browser log support
1 parent 3a47f27 commit a9a209d

File tree

8 files changed

+201
-6
lines changed

8 files changed

+201
-6
lines changed

inc/commands/log_command.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ namespace webdriver {
1818

1919
class Response;
2020

21-
class LogCommand : public WebDriverCommand {
21+
class LogCommand : public ViewCommand {
2222
public:
2323
LogCommand(const std::vector<std::string>& path_segments,
2424
const base::DictionaryValue* parameters);

inc/extension_qt/web_view_executor.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define WEBDRIVER_QT_WEB_VIEW_EXECUTOR_H_
33

44
#include "extension_qt/q_view_executor.h"
5+
#include "webdriver_logging.h"
56

67
#include <QtCore/QtGlobal>
78

@@ -61,6 +62,44 @@ public slots:
6162
bool isCompleted;
6263
};
6364

65+
class JSLogger : public QObject
66+
{
67+
Q_OBJECT
68+
69+
public:
70+
JSLogger();
71+
base::ListValue* getLog();
72+
void SetMinLogLevel(LogLevel level);
73+
74+
public slots:
75+
void log(QVariant message);
76+
void warn(QVariant message);
77+
void error(QVariant message);
78+
79+
private:
80+
InMemoryLog browserLog;
81+
Logger browserLogger;
82+
};
83+
84+
class BrowserLogHandler : public QObject
85+
{
86+
Q_OBJECT
87+
88+
public:
89+
BrowserLogHandler(QObject* parent);
90+
base::ListValue* getLog();
91+
void SetMinLogLevel(LogLevel level);
92+
void loadConsoleJS(const QWebView* view);
93+
void loadJSLogObject(QWebFrame *frame);
94+
95+
public slots:
96+
void loadJSLogObject();
97+
void loadConsoleJS();
98+
99+
private:
100+
JSLogger jslogger;
101+
};
102+
64103
class QWebViewCmdExecutorCreator : public ViewCmdExecutorCreator {
65104
public:
66105
static const ViewType WEB_VIEW_TYPE;
@@ -147,6 +186,7 @@ class QWebViewCmdExecutor : public QViewCmdExecutor {
147186
virtual void TouchScroll(const ElementId &element, const int &xoffset, const int &yoffset, Error **error);
148187
virtual void TouchFlick(const int &xSpeed, const int &ySpeed, Error **error);
149188
virtual void TouchFlick(const ElementId &element, const int &xoffset, const int &yoffset, const int &speed, Error **error);
189+
virtual void GetBrowserLog(base::ListValue** browserLog, Error **error);
150190

151191

152192
protected:
@@ -239,6 +279,8 @@ class QWebViewCmdExecutor : public QViewCmdExecutor {
239279

240280
Error* ToggleOptionElement(const ElementId& element);
241281

282+
void AddBrowserLoggerToView(QWebView* view);
283+
242284

243285

244286

inc/webdriver_logging.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class LogType {
4141
enum Type {
4242
kInvalid = -1, /// invalid type
4343
kDriver, /// driver
44+
kBrowser, /// browser (console.log)
4445
kNum /// number of sources
4546
};
4647

inc/webdriver_view_executor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ class ViewCmdExecutor {
164164
virtual void TouchScroll(const ElementId &element, const int &xoffset, const int &yoffset, Error **error) = 0;
165165
virtual void TouchFlick(const int &xSpeed, const int &ySpeed, Error **error) = 0;
166166
virtual void TouchFlick(const ElementId &element, const int &xoffset, const int &yoffset, const int &speed, Error **error) = 0;
167+
virtual void GetBrowserLog(base::ListValue** browserLog, Error **error) {}
167168

168169
protected:
169170
Session* session_;

src/webdriver/commands/log_command.cc

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,18 @@
66

77
#include "base/string_util.h"
88
#include "base/values.h"
9+
#include "base/bind.h"
910
#include "commands/response.h"
1011
#include "webdriver_error.h"
1112
#include "webdriver_session.h"
13+
#include "webdriver_view_executor.h"
1214

1315
namespace webdriver {
1416

1517
LogCommand::LogCommand(
1618
const std::vector<std::string>& path_segments,
1719
const DictionaryValue* parameters)
18-
: WebDriverCommand(path_segments, parameters) {
20+
: ViewCommand(path_segments, parameters) {
1921
}
2022

2123
LogCommand::~LogCommand() {
@@ -40,7 +42,31 @@ void LogCommand::ExecutePost(Response* const response) {
4042

4143
if (log_type.type() == LogType::kDriver) {
4244
response->SetValue(session_->GetLog());
43-
} else {
45+
}
46+
else if (log_type.type() == LogType::kBrowser) {
47+
Error* error = NULL;
48+
base::ListValue* browserLog = NULL;
49+
50+
session_->RunSessionTask(base::Bind(
51+
&ViewCmdExecutor::GetBrowserLog,
52+
base::Unretained(executor_.get()),
53+
&browserLog,
54+
&error));
55+
56+
if (error)
57+
response->SetError(error);
58+
else if (browserLog == NULL)
59+
{
60+
browserLog = new base::ListValue();
61+
response->SetValue(browserLog);
62+
}
63+
else
64+
{
65+
response->SetValue(browserLog);
66+
}
67+
}
68+
else
69+
{
4470
response->SetError(new Error(kUnknownError, "Unrecognized type: " + type));
4571
return;
4672
}
@@ -62,7 +88,7 @@ bool LogTypesCommand::DoesGet() const {
6288
void LogTypesCommand::ExecuteGet(Response* const response) {
6389
base::ListValue* logTypes_list = new base::ListValue();
6490
logTypes_list->Append(Value::CreateStringValue(LogType(LogType::kDriver).ToString()));
65-
91+
logTypes_list->Append(Value::CreateStringValue(LogType(LogType::kBrowser).ToString()));
6692
response->SetValue(logTypes_list);
6793
}
6894

src/webdriver/extension_qt/web_view_executor.cc

Lines changed: 121 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,96 @@ void JSNotifier::setResult(QVariant result)
7777
emit completed();
7878
}
7979

80+
BrowserLogHandler::BrowserLogHandler(QObject *parent): QObject(parent), jslogger()
81+
{
82+
}
83+
84+
base::ListValue* BrowserLogHandler::getLog()
85+
{
86+
return jslogger.getLog();
87+
}
88+
89+
void BrowserLogHandler::SetMinLogLevel(LogLevel level)
90+
{
91+
jslogger.SetMinLogLevel(level);
92+
}
93+
94+
void BrowserLogHandler::loadJSLogObject()
95+
{
96+
QWebFrame *mainFrame = qobject_cast<QWebFrame*>(sender());
97+
if (mainFrame)
98+
loadJSLogObject(mainFrame);
99+
}
100+
101+
void BrowserLogHandler::loadJSLogObject(QWebFrame *frame)
102+
{
103+
frame->addToJavaScriptWindowObject("wdconsole", &jslogger);
104+
}
105+
106+
void BrowserLogHandler::loadConsoleJS()
107+
{
108+
QWebView* view = qobject_cast<QWebView*>(sender());
109+
if (view)
110+
loadConsoleJS(view);
111+
}
112+
113+
void BrowserLogHandler::loadConsoleJS(const QWebView *view)
114+
{
115+
QString jscript ("if ( _log == null ){"
116+
"var _log = console.log,"
117+
"_warn = console.warn,"
118+
"_error = console.error;"
119+
"};"
120+
121+
"console.log = function() {"
122+
"wdconsole.log(arguments[0]);"
123+
"return _log.apply(console, arguments);"
124+
"};"
125+
126+
"console.warn = function() {"
127+
"wdconsole.warn(arguments[0]);"
128+
"return _warn.apply(console, arguments);"
129+
"};"
130+
131+
"console.error = function() {"
132+
"wdconsole.error(arguments[0]);"
133+
"return _error.apply(console, arguments);"
134+
"};");
135+
view->page()->mainFrame()->evaluateJavaScript(jscript);
136+
}
137+
138+
JSLogger::JSLogger()
139+
{
140+
browserLogger.AddHandler(&browserLog);
141+
}
142+
143+
base::ListValue* JSLogger::getLog()
144+
{
145+
base::ListValue* retVal = browserLog.entries_list()->DeepCopy();
146+
browserLog.clear_entries_list();
147+
return retVal;
148+
}
149+
150+
void JSLogger::SetMinLogLevel(LogLevel level)
151+
{
152+
browserLogger.set_min_log_level(level);
153+
}
154+
155+
void JSLogger::log(QVariant message)
156+
{
157+
browserLogger.Log(kInfoLogLevel, message.toString().toStdString());
158+
}
159+
160+
void JSLogger::warn(QVariant message)
161+
{
162+
browserLogger.Log(kWarningLogLevel, message.toString().toStdString());
163+
}
164+
165+
void JSLogger::error(QVariant message)
166+
{
167+
browserLogger.Log(kSevereLogLevel, message.toString().toStdString());
168+
}
169+
80170
const ViewType QWebViewCmdExecutorCreator::WEB_VIEW_TYPE = 0x13f0;
81171

82172
QWebViewCmdExecutorCreator::QWebViewCmdExecutorCreator()
@@ -771,6 +861,8 @@ void QWebViewCmdExecutor::SwitchTo(Error** error) {
771861

772862
session_->logger().Log(kInfoLogLevel, "SwitchTo - set current view ("+view_id_.id()+")");
773863

864+
AddBrowserLoggerToView(view);
865+
774866
// reset frame path
775867
session_->frame_elements_.clear();
776868
session_->set_current_frame(FramePath());
@@ -1464,6 +1556,19 @@ void QWebViewCmdExecutor::TouchFlick(const ElementId &element, const int &xoffse
14641556
view->page()->mainFrame()->scroll(-xoffset*(speed+1), -yoffset*(speed+1));
14651557
}
14661558

1559+
void QWebViewCmdExecutor::GetBrowserLog(base::ListValue** browserLog, Error **error)
1560+
{
1561+
QWebView* view = getView(view_id_, error);
1562+
if (NULL == view)
1563+
return;
1564+
1565+
BrowserLogHandler* logHandler = view->findChild<BrowserLogHandler*>();
1566+
if (NULL == logHandler)
1567+
return;
1568+
1569+
*browserLog = logHandler->getLog();
1570+
}
1571+
14671572
QWebFrame* QWebViewCmdExecutor::FindFrameByPath(QWebFrame* parent, const FramePath &frame_path) {
14681573
if (frame_path.value().empty())
14691574
return NULL;
@@ -1984,7 +2089,7 @@ Error* QWebViewCmdExecutor::SwitchToFrameWithJavaScriptLocatedFrame(
19842089
std::string frame_id = GenerateRandomID();
19852090
error = ExecuteScriptAndParse(
19862091
frame,
1987-
"function(elem, id) { var meta; elem.setAttribute('wd_frame_id_', id); var doc = elem.contentDocument? elem.contentDocument: elem.contentWindow.document; meta=doc.createElement('meta'); meta.name = 'wd_frame_id_'; meta.content = id; var child = doc.body.appendChild(meta); console.log(meta); console.log(child);}",
2092+
"function(elem, id) { var meta; elem.setAttribute('wd_frame_id_', id); var doc = elem.contentDocument? elem.contentDocument: elem.contentWindow.document; meta=doc.createElement('meta'); meta.name = 'wd_frame_id_'; meta.content = id; var child = doc.body.appendChild(meta);}",
19882093
"setFrameId",
19892094
CreateListValueFrom(new_frame_element, frame_id),
19902095
CreateDirectValueParser(kSkipParsing));
@@ -2107,5 +2212,20 @@ Error* QWebViewCmdExecutor::ToggleOptionElement(const ElementId& element) {
21072212
return error;
21082213
}
21092214

2215+
void QWebViewCmdExecutor::AddBrowserLoggerToView(QWebView* view)
2216+
{
2217+
BrowserLogHandler* logHandler = view->findChild<BrowserLogHandler*>();
2218+
if (NULL == logHandler)
2219+
{
2220+
logHandler = new BrowserLogHandler(view);
2221+
logHandler->SetMinLogLevel(session_->capabilities().log_levels[LogType::kBrowser]);
2222+
}
2223+
2224+
QObject::connect(view->page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), logHandler, SLOT(loadJSLogObject()));
2225+
QObject::connect(view, SIGNAL(loadFinished(bool)),logHandler, SLOT(loadConsoleJS()), Qt::QueuedConnection);
2226+
logHandler->loadJSLogObject(view->page()->mainFrame());
2227+
logHandler->loadConsoleJS(view);
2228+
}
2229+
21102230

21112231
} //namespace webdriver

src/webdriver/webdriver_capabilities_parser.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ Capabilities::Capabilities()
6262
load_async(false),
6363
caps(new DictionaryValue()) {
6464
log_levels[LogType::kDriver] = kAllLogLevel;
65+
log_levels[LogType::kBrowser] = kAllLogLevel;
6566
}
6667

6768
Capabilities::~Capabilities() { }

src/webdriver/webdriver_logging.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@ std::string LogLevelToString(LogLevel level) {
6969
bool LogType::FromString(const std::string& name, LogType* log_type) {
7070
if (name == "driver") {
7171
*log_type = LogType(kDriver);
72-
} else {
72+
} else if (name == "browser") {
73+
*log_type = LogType(kBrowser);
74+
} else{
7375
return false;
7476
}
7577
return true;
@@ -85,6 +87,8 @@ std::string LogType::ToString() const {
8587
switch (type_) {
8688
case kDriver:
8789
return "driver";
90+
case kBrowser:
91+
return "browser";
8892
default:
8993
return "unknown";
9094
};

0 commit comments

Comments
 (0)