1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_TEST_AUTOMATION_JAVASCRIPT_EXECUTION_CONTROLLER_H_
#define CHROME_TEST_AUTOMATION_JAVASCRIPT_EXECUTION_CONTROLLER_H_
#pragma once
#include <map>
#include <string>
#include "base/scoped_ptr.h"
#include "base/values.h"
#include "base/weak_ptr.h"
#include "chrome/test/automation/javascript_message_utils.h"
class JavaScriptObjectProxy;
// This class handles the execution of arbitrary JavaScript, preparing it for
// execution, and parsing its result (in JSON). It keeps track of all returned
// JavaScript objects.
class JavaScriptExecutionController
: public base::SupportsWeakPtr<JavaScriptExecutionController> {
public:
JavaScriptExecutionController() {}
virtual ~JavaScriptExecutionController() {}
// Executes |script| and parse the return value. Returns whether the
// execution and parsing succeeded.
template <typename T>
bool ExecuteJavaScriptAndGetReturn(const std::string& script, T* result) {
scoped_ptr<Value> returnValue;
if (!ExecuteAndParseHelper(WrapJavaScript(script), &returnValue))
return false;
return ValueConversionTraits<T>::SetFromValue(returnValue.get(), result);
}
// Similar to above, except that it does not get the return value.
bool ExecuteJavaScript(const std::string& script);
// Executes |script|, waits for it to send a JSON response, and parses the
// return value. This call itself blocks, but the JavaScript responds
// asynchronously. Returns whether the execution and parsing succeeded.
// Will return false on timeouts.
template <typename T>
bool ExecuteAsyncJavaScriptAndGetReturn(const std::string& script,
T* result) {
scoped_ptr<Value> returnValue;
if (!ExecuteAndParseHelper(WrapAsyncJavaScript(script), &returnValue))
return false;
return ValueConversionTraits<T>::SetFromValue(returnValue.get(), result);
}
// Similar to above, except that it does not get the return value.
bool ExecuteAsyncJavaScript(const std::string& script);
// Returns the proxy associated with |handle|, creating one if necessary.
// The proxy must be inherit JavaScriptObjectProxy.
template<class JavaScriptObject>
JavaScriptObject* GetObjectProxy(int handle) {
JavaScriptObject* obj = NULL;
HandleToObjectMap::const_iterator iter = handle_to_object_.find(handle);
if (iter == handle_to_object_.end()) {
obj = new JavaScriptObject(this, handle);
if (handle_to_object_.empty())
FirstObjectAdded();
handle_to_object_.insert(std::make_pair(handle, obj));
} else {
obj = static_cast<JavaScriptObject*>(iter->second);
}
return obj;
}
// Sets a timeout to be used for all JavaScript methods in which a response
// is returned asynchronously.
static void set_timeout(int timeout_ms) { timeout_ms_ = timeout_ms; }
protected:
// Executes |script| and sets the JSON response |json|. Returns true
// on success.
virtual bool ExecuteJavaScriptAndGetJSON(const std::string& script,
std::string* json) = 0;
// Called when this controller is tracking its first object. Used by
// reference counted subclasses.
virtual void FirstObjectAdded() {}
// Called when this controller is no longer tracking any objects. Used by
// reference counted subclasses.
virtual void LastObjectRemoved() {}
private:
typedef std::map<int, JavaScriptObjectProxy*> HandleToObjectMap;
friend class JavaScriptObjectProxy;
// Called by JavaScriptObjectProxy on destruction.
void Remove(int handle);
// Helper method for executing JavaScript and parsing the JSON response.
// If successful, returns true and sets |returnValue| as the script's return
// value.
bool ExecuteAndParseHelper(const std::string& script,
scoped_ptr<Value>* returnValue);
// Returns |script| wrapped and prepared for proper JavaScript execution,
// via the JavaScript function domAutomation.evaluateJavaScript.
std::string WrapJavaScript(const std::string& script);
// Returns |script| wrapped and prepared for proper JavaScript execution
// via the JavaScript function domAutomation.evaluateAsyncJavaScript.
std::string WrapAsyncJavaScript(const std::string& script);
// Timeout to use for all asynchronous methods.
static int timeout_ms_;
// Weak pointer to all the object proxies that we create.
HandleToObjectMap handle_to_object_;
DISALLOW_COPY_AND_ASSIGN(JavaScriptExecutionController);
};
#endif // CHROME_TEST_AUTOMATION_JAVASCRIPT_EXECUTION_CONTROLLER_H_
|