| Index: chrome/test/webdriver/session.cc
|
| diff --git a/chrome/test/webdriver/session.cc b/chrome/test/webdriver/session.cc
|
| index bbfdc49428628e5ce2efd86a2bac5126a4557afa..51b2908f342523fc668e36cd224f77cf5ebd8593 100644
|
| --- a/chrome/test/webdriver/session.cc
|
| +++ b/chrome/test/webdriver/session.cc
|
| @@ -32,14 +32,12 @@
|
| #include "chrome/common/chrome_constants.h"
|
| #include "chrome/common/chrome_switches.h"
|
| #include "chrome/test/automation/automation_json_requests.h"
|
| -#include "chrome/test/webdriver/webdriver_error.h"
|
| +#include "chrome/test/automation/value_conversion_util.h"
|
| #include "chrome/test/webdriver/session_manager.h"
|
| -#include "chrome/test/webdriver/utility_functions.h"
|
| +#include "chrome/test/webdriver/webdriver_error.h"
|
| #include "chrome/test/webdriver/webdriver_key_converter.h"
|
| +#include "chrome/test/webdriver/webdriver_util.h"
|
| #include "third_party/webdriver/atoms.h"
|
| -#include "ui/gfx/point.h"
|
| -#include "ui/gfx/rect.h"
|
| -#include "ui/gfx/size.h"
|
|
|
| namespace webdriver {
|
|
|
| @@ -131,7 +129,7 @@ Error* Session::ExecuteScript(const FrameId& frame_id,
|
| "[function(){%s\n},%s,true]));",
|
| atoms::EXECUTE_SCRIPT, script.c_str(), args_as_json.c_str());
|
|
|
| - return ExecuteScriptAndParseResponse(frame_id, jscript, value);
|
| + return ExecuteScriptAndParseValue(frame_id, jscript, value);
|
| }
|
|
|
| Error* Session::ExecuteScript(const std::string& script,
|
| @@ -140,6 +138,32 @@ Error* Session::ExecuteScript(const std::string& script,
|
| return ExecuteScript(current_target_, script, args, value);
|
| }
|
|
|
| +Error* Session::ExecuteScriptAndParse(const FrameId& frame_id,
|
| + const std::string& anonymous_func_script,
|
| + const std::string& script_name,
|
| + const ListValue* args,
|
| + const ValueParser* parser) {
|
| + scoped_ptr<const ListValue> scoped_args(args);
|
| + scoped_ptr<const ValueParser> scoped_parser(parser);
|
| + std::string called_script = base::StringPrintf(
|
| + "return (%s).apply(null, arguments);", anonymous_func_script.c_str());
|
| + Value* unscoped_value = NULL;
|
| + Error* error = ExecuteScript(frame_id, called_script, args, &unscoped_value);
|
| + if (error) {
|
| + error->AddDetails(script_name + " execution failed");
|
| + return error;
|
| + }
|
| +
|
| + scoped_ptr<Value> value(unscoped_value);
|
| + std::string error_msg;
|
| + if (!parser->Parse(value.get())) {
|
| + error_msg = base::StringPrintf("%s returned invalid value: %s",
|
| + script_name.c_str(), JsonStringify(value.get()).c_str());
|
| + return new Error(kUnknownError, error_msg);
|
| + }
|
| + return NULL;
|
| +}
|
| +
|
| Error* Session::ExecuteAsyncScript(const FrameId& frame_id,
|
| const std::string& script,
|
| const ListValue* const args,
|
| @@ -162,7 +186,7 @@ Error* Session::ExecuteAsyncScript(const FrameId& frame_id,
|
| timeout_ms,
|
| "function(result) {window.domAutomationController.send(result);}");
|
|
|
| - return ExecuteScriptAndParseResponse(frame_id, jscript, value);
|
| + return ExecuteScriptAndParseValue(frame_id, jscript, value);
|
| }
|
|
|
| Error* Session::SendKeys(const WebElementId& element, const string16& keys) {
|
| @@ -181,8 +205,6 @@ Error* Session::SendKeys(const WebElementId& element, const string16& keys) {
|
| if (!is_enabled)
|
| return new Error(kInvalidElementState);
|
|
|
| - ListValue args;
|
| - args.Append(element.ToValue());
|
| // Focus the target element in order to send keys to it.
|
| // First, the currently active element is blurred, if it is different from
|
| // the target element. We do not want to blur an element unnecessarily,
|
| @@ -202,24 +224,27 @@ Error* Session::SendKeys(const WebElementId& element, const string16& keys) {
|
| // - You cannot focus a descendant of a content editable node
|
| // TODO(jleyba): Update this to use the correct atom.
|
| const char* kFocusScript =
|
| - "var elem = arguments[0];"
|
| - "var doc = elem.ownerDocument || elem;"
|
| - "var prevActiveElem = doc.activeElement;"
|
| - "if (elem != prevActiveElem && prevActiveElem)"
|
| - " prevActiveElem.blur();"
|
| - "elem.focus();"
|
| - "if (elem != prevActiveElem && elem.value && elem.value.length &&"
|
| - " elem.setSelectionRange) {"
|
| - " elem.setSelectionRange(elem.value.length, elem.value.length);"
|
| - "}"
|
| - "if (elem != doc.activeElement)"
|
| - " throw new Error('Failed to send keys because cannot focus element.');";
|
| - Value* unscoped_result = NULL;
|
| - error = ExecuteScript(kFocusScript, &args, &unscoped_result);
|
| + "function(elem) {"
|
| + " var doc = elem.ownerDocument || elem;"
|
| + " var prevActiveElem = doc.activeElement;"
|
| + " if (elem != prevActiveElem && prevActiveElem)"
|
| + " prevActiveElem.blur();"
|
| + " elem.focus();"
|
| + " if (elem != prevActiveElem && elem.value && elem.value.length &&"
|
| + " elem.setSelectionRange) {"
|
| + " elem.setSelectionRange(elem.value.length, elem.value.length);"
|
| + " }"
|
| + " if (elem != doc.activeElement)"
|
| + " throw new Error('Failed to send keys because cannot focus element');"
|
| + "}";
|
| + error = ExecuteScriptAndParse(current_target_,
|
| + kFocusScript,
|
| + "focusElement",
|
| + CreateListValueFrom(element),
|
| + CreateDirectValueParser(kSkipParsing));
|
| if (error)
|
| return error;
|
|
|
| - error = NULL;
|
| RunSessionTask(NewRunnableMethod(
|
| this,
|
| &Session::SendKeysOnSessionThread,
|
| @@ -229,7 +254,7 @@ Error* Session::SendKeys(const WebElementId& element, const string16& keys) {
|
| }
|
|
|
| Error* Session::DragAndDropFilePaths(
|
| - const gfx::Point& location,
|
| + const Point& location,
|
| const std::vector<FilePath::StringType>& paths) {
|
| Error* error = NULL;
|
| RunSessionTask(NewRunnableMethod(
|
| @@ -293,44 +318,29 @@ Error* Session::Reload() {
|
| }
|
|
|
| Error* Session::GetURL(std::string* url) {
|
| - ListValue no_args;
|
| - Value* unscoped_value = NULL;
|
| - Error* error = ExecuteScript(current_target_,
|
| - "return document.URL;",
|
| - &no_args,
|
| - &unscoped_value);
|
| - scoped_ptr<Value> value(unscoped_value);
|
| - if (error)
|
| - return error;
|
| - if (!value->GetAsString(url))
|
| - return new Error(kUnknownError, "GetURL Script returned non-string: " +
|
| - JsonStringify(value.get()));
|
| - return NULL;
|
| + return ExecuteScriptAndParse(current_target_,
|
| + "function() { return document.URL }",
|
| + "getUrl",
|
| + new ListValue(),
|
| + CreateDirectValueParser(url));
|
| }
|
|
|
| Error* Session::GetTitle(std::string* tab_title) {
|
| - std::string script =
|
| - "if (document.title)"
|
| - " return document.title;"
|
| - "else"
|
| - " return document.URL;";
|
| -
|
| - ListValue no_args;
|
| - Value* unscoped_value = NULL;
|
| - Error* error = ExecuteScript(current_target_,
|
| - script,
|
| - &no_args,
|
| - &unscoped_value);
|
| - scoped_ptr<Value> value(unscoped_value);
|
| - if (error)
|
| - return error;
|
| - if (!value->GetAsString(tab_title))
|
| - return new Error(kUnknownError, "GetTitle script returned non-string: " +
|
| - JsonStringify(value.get()));
|
| - return NULL;
|
| -}
|
| -
|
| -Error* Session::MouseMoveAndClick(const gfx::Point& location,
|
| + const char* kGetTitleScript =
|
| + "function() {"
|
| + " if (document.title)"
|
| + " return document.title;"
|
| + " else"
|
| + " return document.URL;"
|
| + "}";
|
| + return ExecuteScriptAndParse(current_target_,
|
| + kGetTitleScript,
|
| + "getTitle",
|
| + new ListValue(),
|
| + CreateDirectValueParser(tab_title));
|
| +}
|
| +
|
| +Error* Session::MouseMoveAndClick(const Point& location,
|
| automation::MouseButton button) {
|
| Error* error = NULL;
|
| RunSessionTask(NewRunnableMethod(
|
| @@ -345,7 +355,7 @@ Error* Session::MouseMoveAndClick(const gfx::Point& location,
|
| return error;
|
| }
|
|
|
| -Error* Session::MouseMove(const gfx::Point& location) {
|
| +Error* Session::MouseMove(const Point& location) {
|
| Error* error = NULL;
|
| RunSessionTask(NewRunnableMethod(
|
| automation_.get(),
|
| @@ -358,8 +368,8 @@ Error* Session::MouseMove(const gfx::Point& location) {
|
| return error;
|
| }
|
|
|
| -Error* Session::MouseDrag(const gfx::Point& start,
|
| - const gfx::Point& end) {
|
| +Error* Session::MouseDrag(const Point& start,
|
| + const Point& end) {
|
| Error* error = NULL;
|
| RunSessionTask(NewRunnableMethod(
|
| automation_.get(),
|
| @@ -480,18 +490,16 @@ Error* Session::SwitchToWindow(const std::string& name) {
|
| return error;
|
| // See if any of the window names match |name|.
|
| for (size_t i = 0; i < window_ids.size(); ++i) {
|
| - ListValue empty_list;
|
| - Value* unscoped_name_value = NULL;
|
| std::string window_name;
|
| - Error* error = ExecuteScript(FrameId(window_ids[i], FramePath()),
|
| - "return window.name;",
|
| - &empty_list,
|
| - &unscoped_name_value);
|
| + Error* error = ExecuteScriptAndParse(
|
| + FrameId(window_ids[i], FramePath()),
|
| + "function() { return window.name; }",
|
| + "getWindowName",
|
| + new ListValue(),
|
| + CreateDirectValueParser(&window_name));
|
| if (error)
|
| return error;
|
| - scoped_ptr<Value> name_value(unscoped_name_value);
|
| - if (name_value->GetAsString(&window_name) &&
|
| - name == window_name) {
|
| + if (name == window_name) {
|
| switch_to_id = window_ids[i];
|
| break;
|
| }
|
| @@ -507,21 +515,21 @@ Error* Session::SwitchToWindow(const std::string& name) {
|
|
|
| Error* Session::SwitchToFrameWithNameOrId(const std::string& name_or_id) {
|
| std::string script =
|
| - "var arg = arguments[0];"
|
| - "var xpath = '(/html/body//iframe|/html/frameset/frame)';"
|
| - "var sub = function(s) { return s.replace(/\\$/g, arg); };"
|
| - "xpath += sub('[@name=\"$\" or @id=\"$\"]');"
|
| - "var frame = document.evaluate(xpath, document, null, "
|
| - " XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;"
|
| - "if (!frame) { return null; }"
|
| - "xpath = frame.tagName == 'IFRAME' ? '/html/body//iframe'"
|
| - " : '/html/frameset/frame';"
|
| - "frame_xpath = xpath + "
|
| - " sub('[@' + (frame.id == arg ? 'id' : 'name') + '=\"$\"]');"
|
| - "return [frame, frame_xpath];";
|
| - ListValue args;
|
| - args.Append(new StringValue(name_or_id));
|
| - return SwitchToFrameWithJavaScriptLocatedFrame(script, &args);
|
| + "function(arg) {"
|
| + " var xpath = '(/html/body//iframe|/html/frameset/frame)';"
|
| + " var sub = function(s) { return s.replace(/\\$/g, arg); };"
|
| + " xpath += sub('[@name=\"$\" or @id=\"$\"]');"
|
| + " var frame = document.evaluate(xpath, document, null, "
|
| + " XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;"
|
| + " if (!frame) { return null; }"
|
| + " xpath = frame.tagName == 'IFRAME' ? '/html/body//iframe'"
|
| + " : '/html/frameset/frame';"
|
| + " frame_xpath = xpath + "
|
| + " sub('[@' + (frame.id == arg ? 'id' : 'name') + '=\"$\"]');"
|
| + " return [frame, frame_xpath];"
|
| + "}";
|
| + return SwitchToFrameWithJavaScriptLocatedFrame(
|
| + script, CreateListValueFrom(name_or_id));
|
| }
|
|
|
| Error* Session::SwitchToFrameWithIndex(int index) {
|
| @@ -533,43 +541,39 @@ Error* Session::SwitchToFrameWithIndex(int index) {
|
| // into the list of all IFRAME and FRAME elements on the page - if we find
|
| // something, then that XPath expression can be used as the new frame's XPath.
|
| std::string script =
|
| - "var index = '[' + (arguments[0] + 1) + ']';"
|
| - "var xpath = '(/html/body//iframe|/html/frameset/frame)' + "
|
| - " index;"
|
| - "console.info('searching for frame by xpath: ' + xpath);"
|
| - "var frame = document.evaluate(xpath, document, null, "
|
| - "XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;"
|
| - "console.info(frame == null ? 'found nothing' : frame);"
|
| - "if (!frame) { return null; }"
|
| - "frame_xpath = ((frame.tagName == 'IFRAME' ? "
|
| - " '(/html/body//iframe)' : '/html/frameset/frame') + index);"
|
| - "return [frame, frame_xpath];";
|
| - ListValue args;
|
| - args.Append(Value::CreateIntegerValue(index));
|
| - return SwitchToFrameWithJavaScriptLocatedFrame(script, &args);
|
| + "function(index) {"
|
| + " var xpathIndex = '[' + (index + 1) + ']';"
|
| + " var xpath = '(/html/body//iframe|/html/frameset/frame)' + "
|
| + " xpathIndex;"
|
| + " var frame = document.evaluate(xpath, document, null, "
|
| + " XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;"
|
| + " if (!frame) { return null; }"
|
| + " frame_xpath = ((frame.tagName == 'IFRAME' ? "
|
| + " '(/html/body//iframe)' : '/html/frameset/frame') + xpathIndex);"
|
| + " return [frame, frame_xpath];"
|
| + "}";
|
| + return SwitchToFrameWithJavaScriptLocatedFrame(
|
| + script, CreateListValueFrom(index));
|
| }
|
|
|
| Error* Session::SwitchToFrameWithElement(const WebElementId& element) {
|
| // TODO(jleyba): Extract this, and the other frame switch methods to an atom.
|
| std::string script =
|
| - "var element = arguments[0];"
|
| - "console.info('Attempting to switch to ' + element);"
|
| - "if (element.nodeType != 1 || !/^i?frame$/i.test(element.tagName)) {"
|
| - " console.info('Element is not a frame: ' + element + "
|
| - "' {nodeType:' + element.nodeType + ',tagName:' + element.tagName + '}');"
|
| - " return null;"
|
| - "}"
|
| - "for (var i = 0; i < window.frames.length; i++) {"
|
| - " if (element.contentWindow == window.frames[i]) {"
|
| - " return [element, '(//iframe|//frame)[' + (i + 1) + ']'];"
|
| + "function(elem) {"
|
| + " if (elem.nodeType != 1 || !/^i?frame$/i.test(elem.tagName)) {"
|
| + " console.error('Element is not a frame');"
|
| + " return null;"
|
| " }"
|
| - "}"
|
| - "console.info('Frame is not connected to this DOM tree');"
|
| - "return null;";
|
| -
|
| - ListValue args;
|
| - args.Append(element.ToValue());
|
| - return SwitchToFrameWithJavaScriptLocatedFrame(script, &args);
|
| + " for (var i = 0; i < window.frames.length; i++) {"
|
| + " if (elem.contentWindow == window.frames[i]) {"
|
| + " return [elem, '(//iframe|//frame)[' + (i + 1) + ']'];"
|
| + " }"
|
| + " }"
|
| + " console.info('Frame is not connected to this DOM tree');"
|
| + " return null;"
|
| + "}";
|
| + return SwitchToFrameWithJavaScriptLocatedFrame(
|
| + script, CreateListValueFrom(element));
|
| }
|
|
|
| void Session::SwitchToTopFrame() {
|
| @@ -591,13 +595,12 @@ Error* Session::SwitchToTopFrameIfCurrentFrameInvalid() {
|
| // frame element is valid, otherwise the automation hangs until a timeout.
|
| for (size_t i = 0; i < frame_elements_.size(); ++i) {
|
| FrameId frame_id(current_target_.window_id, frame_path);
|
| - ListValue args;
|
| - args.Append(frame_elements_[i].ToValue());
|
| - Value* unscoped_value = NULL;
|
| - scoped_ptr<Error> error(ExecuteScript(
|
| - frame_id, "", &args, &unscoped_value));
|
| -
|
| - scoped_ptr<Value> value(unscoped_value);
|
| + scoped_ptr<Error> error(ExecuteScriptAndParse(
|
| + frame_id,
|
| + "function(){ }",
|
| + "emptyScript",
|
| + CreateListValueFrom(frame_elements_[i]),
|
| + CreateDirectValueParser(kSkipParsing)));
|
| if (error.get() && error->code() == kStaleElementReference) {
|
| SwitchToTopFrame();
|
| } else if (error.get()) {
|
| @@ -730,26 +733,26 @@ Error* Session::FindElements(const FrameId& frame_id,
|
|
|
| Error* Session::GetElementLocationInView(
|
| const WebElementId& element,
|
| - gfx::Point* location) {
|
| - gfx::Size size;
|
| + Point* location) {
|
| + Size size;
|
| Error* error = GetElementSize(current_target_, element, &size);
|
| if (error)
|
| return error;
|
| return GetElementRegionInView(
|
| - element, gfx::Rect(gfx::Point(0, 0), size),
|
| + element, Rect(Point(0, 0), size),
|
| false /* center */, false /* verify_clickable_at_middle */, location);
|
| }
|
|
|
| Error* Session::GetElementRegionInView(
|
| const WebElementId& element,
|
| - const gfx::Rect& region,
|
| + const Rect& region,
|
| bool center,
|
| bool verify_clickable_at_middle,
|
| - gfx::Point* location) {
|
| + Point* location) {
|
| CHECK(element.is_valid());
|
|
|
| - gfx::Point region_offset = region.origin();
|
| - gfx::Size region_size = region.size();
|
| + Point region_offset = region.origin();
|
| + Size region_size = region.size();
|
| Error* error = GetElementRegionInViewHelper(
|
| current_target_, element, region, center, verify_clickable_at_middle,
|
| ®ion_offset);
|
| @@ -782,7 +785,7 @@ Error* Session::GetElementRegionInView(
|
| region_offset.Offset(border_left, border_top);
|
|
|
| error = GetElementRegionInViewHelper(
|
| - frame_id, frame_element, gfx::Rect(region_offset, region_size),
|
| + frame_id, frame_element, Rect(region_offset, region_size),
|
| center, verify_clickable_at_middle, ®ion_offset);
|
| if (error)
|
| return error;
|
| @@ -793,66 +796,22 @@ Error* Session::GetElementRegionInView(
|
|
|
| Error* Session::GetElementSize(const FrameId& frame_id,
|
| const WebElementId& element,
|
| - gfx::Size* size) {
|
| - std::string script = base::StringPrintf(
|
| - "return (%s).apply(null, arguments);", atoms::GET_SIZE);
|
| - ListValue args;
|
| - args.Append(element.ToValue());
|
| -
|
| - Value* unscoped_result = NULL;
|
| - Error* error = ExecuteScript(frame_id, script, &args, &unscoped_result);
|
| - scoped_ptr<Value> result(unscoped_result);
|
| - if (error)
|
| - return error;
|
| - if (!result->IsType(Value::TYPE_DICTIONARY)) {
|
| - return new Error(kUnknownError, "GetSize atom returned non-dict type: " +
|
| - JsonStringify(result.get()));
|
| - }
|
| - DictionaryValue* dict = static_cast<DictionaryValue*>(result.get());
|
| - int width, height;
|
| - if (!dict->GetInteger("width", &width) ||
|
| - !dict->GetInteger("height", &height)) {
|
| - return new Error(kUnknownError, "GetSize atom returned invalid dict: " +
|
| - JsonStringify(dict));
|
| - }
|
| - *size = gfx::Size(width, height);
|
| - return NULL;
|
| + Size* size) {
|
| + return ExecuteScriptAndParse(frame_id,
|
| + atoms::GET_SIZE,
|
| + "getSize",
|
| + CreateListValueFrom(element),
|
| + CreateDirectValueParser(size));
|
| }
|
|
|
| Error* Session::GetElementFirstClientRect(const FrameId& frame_id,
|
| const WebElementId& element,
|
| - gfx::Rect* rect) {
|
| - std::string script = base::StringPrintf(
|
| - "return (%s).apply(null, arguments);", atoms::GET_FIRST_CLIENT_RECT);
|
| - ListValue args;
|
| - args.Append(element.ToValue());
|
| -
|
| - Value* unscoped_result = NULL;
|
| - Error* error = ExecuteScript(frame_id, script, &args, &unscoped_result);
|
| - scoped_ptr<Value> result(unscoped_result);
|
| - if (error)
|
| - return error;
|
| - if (!result->IsType(Value::TYPE_DICTIONARY)) {
|
| - return new Error(
|
| - kUnknownError,
|
| - "GetFirstClientRect atom returned non-dict type: " +
|
| - JsonStringify(result.get()));
|
| - }
|
| - DictionaryValue* dict = static_cast<DictionaryValue*>(result.get());
|
| - // TODO(kkania): Convert the atom to return integers.
|
| - double left, top, width, height;
|
| - if (!dict->GetDouble("left", &left) ||
|
| - !dict->GetDouble("top", &top) ||
|
| - !dict->GetDouble("width", &width) ||
|
| - !dict->GetDouble("height", &height)) {
|
| - return new Error(
|
| - kUnknownError,
|
| - "GetFirstClientRect atom returned invalid dict: " +
|
| - JsonStringify(dict));
|
| - }
|
| - *rect = gfx::Rect(static_cast<int>(left), static_cast<int>(top),
|
| - static_cast<int>(width), static_cast<int>(height));
|
| - return NULL;
|
| + Rect* rect) {
|
| + return ExecuteScriptAndParse(frame_id,
|
| + atoms::GET_FIRST_CLIENT_RECT,
|
| + "getFirstClientRect",
|
| + CreateListValueFrom(element),
|
| + CreateDirectValueParser(rect));
|
| }
|
|
|
| Error* Session::GetElementEffectiveStyle(
|
| @@ -860,28 +819,11 @@ Error* Session::GetElementEffectiveStyle(
|
| const WebElementId& element,
|
| const std::string& prop,
|
| std::string* value) {
|
| - std::string script = base::StringPrintf(
|
| - "return (%s).apply(null, arguments);", atoms::GET_EFFECTIVE_STYLE);
|
| - ListValue args;
|
| - args.Append(element.ToValue());
|
| - args.Append(Value::CreateStringValue(prop));
|
| - Value* unscoped_result = NULL;
|
| - Error* error = ExecuteScript(
|
| - frame_id, script, &args, &unscoped_result);
|
| - scoped_ptr<Value> result(unscoped_result);
|
| - if (error) {
|
| - error->AddDetails(base::StringPrintf(
|
| - "GetEffectiveStyle atom failed for property (%s)", prop.c_str()));
|
| - return error;
|
| - }
|
| -
|
| - if (!result->GetAsString(value)) {
|
| - std::string context = base::StringPrintf(
|
| - "GetEffectiveStyle atom returned non-string for property (%s): %s",
|
| - prop.c_str(), JsonStringify(result.get()).c_str());
|
| - return new Error(kUnknownError, context);
|
| - }
|
| - return NULL;
|
| + return ExecuteScriptAndParse(frame_id,
|
| + atoms::GET_EFFECTIVE_STYLE,
|
| + "getEffectiveStyle",
|
| + CreateListValueFrom(element, prop),
|
| + CreateDirectValueParser(value));
|
| }
|
|
|
| Error* Session::GetElementBorder(const FrameId& frame_id,
|
| @@ -907,77 +849,42 @@ Error* Session::IsElementDisplayed(const FrameId& frame_id,
|
| const WebElementId& element,
|
| bool ignore_opacity,
|
| bool* is_displayed) {
|
| - std::string script = base::StringPrintf(
|
| - "return (%s).apply(null, arguments);", atoms::IS_DISPLAYED);
|
| - ListValue args;
|
| - args.Append(element.ToValue());
|
| - args.Append(Value::CreateBooleanValue(ignore_opacity));
|
| -
|
| - Value* unscoped_result = NULL;
|
| - Error* error = ExecuteScript(frame_id, script, &args, &unscoped_result);
|
| - scoped_ptr<Value> result(unscoped_result);
|
| - if (error)
|
| - return error;
|
| - if (!result->GetAsBoolean(is_displayed))
|
| - return new Error(kUnknownError, "IsDisplayed atom returned non-boolean: " +
|
| - JsonStringify(result.get()));
|
| - return NULL;
|
| + return ExecuteScriptAndParse(frame_id,
|
| + atoms::IS_DISPLAYED,
|
| + "isDisplayed",
|
| + CreateListValueFrom(element, ignore_opacity),
|
| + CreateDirectValueParser(is_displayed));
|
| }
|
|
|
| Error* Session::IsElementEnabled(const FrameId& frame_id,
|
| const WebElementId& element,
|
| bool* is_enabled) {
|
| - std::string script = base::StringPrintf(
|
| - "return (%s).apply(null, arguments);", atoms::IS_ENABLED);
|
| - ListValue args;
|
| - args.Append(element.ToValue());
|
| -
|
| - Value* unscoped_result = NULL;
|
| - Error* error = ExecuteScript(frame_id, script, &args, &unscoped_result);
|
| - scoped_ptr<Value> result(unscoped_result);
|
| - if (error)
|
| - return error;
|
| - if (!result->GetAsBoolean(is_enabled))
|
| - return new Error(kUnknownError, "IsEnabled atom returned non-boolean: " +
|
| - JsonStringify(result.get()));
|
| - return NULL;
|
| + return ExecuteScriptAndParse(frame_id,
|
| + atoms::IS_ENABLED,
|
| + "isEnabled",
|
| + CreateListValueFrom(element),
|
| + CreateDirectValueParser(is_enabled));
|
| }
|
|
|
| Error* Session::IsOptionElementSelected(const FrameId& frame_id,
|
| const WebElementId& element,
|
| bool* is_selected) {
|
| - ListValue args;
|
| - args.Append(element.ToValue());
|
| -
|
| - std::string script = base::StringPrintf(
|
| - "return (%s).apply(null, arguments);", atoms::IS_SELECTED);
|
| -
|
| - Value* result = NULL;
|
| - Error* error = ExecuteScript(frame_id, script, &args, &result);
|
| - if (error)
|
| - return error;
|
| - scoped_ptr<Value> scoped_result(result);
|
| - if (!result->GetAsBoolean(is_selected)) {
|
| - return new Error(kUnknownError, "isSelected atom returned non-boolean: " +
|
| - JsonStringify(result));
|
| - }
|
| - return NULL;
|
| + return ExecuteScriptAndParse(
|
| + frame_id,
|
| + atoms::IS_SELECTED,
|
| + "isSelected",
|
| + CreateListValueFrom(element),
|
| + CreateDirectValueParser(is_selected));
|
| }
|
|
|
| Error* Session::SetOptionElementSelected(const FrameId& frame_id,
|
| const WebElementId& element,
|
| bool selected) {
|
| - ListValue args;
|
| - args.Append(element.ToValue());
|
| - args.Append(Value::CreateBooleanValue(selected));
|
| -
|
| - std::string script = base::StringPrintf(
|
| - "return (%s).apply(null, arguments);", atoms::SET_SELECTED);
|
| -
|
| - Value* unscoped_result = NULL;
|
| - Error* error = ExecuteScript(frame_id, script, &args, &unscoped_result);
|
| - scoped_ptr<Value> result(unscoped_result);
|
| - return error;
|
| + return ExecuteScriptAndParse(frame_id,
|
| + atoms::SET_SELECTED,
|
| + "setSelected",
|
| + CreateListValueFrom(element, selected),
|
| + CreateDirectValueParser(kSkipParsing));
|
| }
|
|
|
| Error* Session::ToggleOptionElement(const FrameId& frame_id,
|
| @@ -993,24 +900,16 @@ Error* Session::ToggleOptionElement(const FrameId& frame_id,
|
| Error* Session::GetElementTagName(const FrameId& frame_id,
|
| const WebElementId& element,
|
| std::string* tag_name) {
|
| - ListValue args;
|
| - args.Append(element.ToValue());
|
| -
|
| - std::string script = "return arguments[0].tagName.toLocaleLowerCase();";
|
| -
|
| - Value* unscoped_result = NULL;
|
| - Error* error = ExecuteScript(frame_id, script, &args, &unscoped_result);
|
| - scoped_ptr<Value> result(unscoped_result);
|
| - if (error)
|
| - return error;
|
| - if (!result->GetAsString(tag_name))
|
| - return new Error(kUnknownError, "TagName script returned non-string: " +
|
| - JsonStringify(result.get()));
|
| - return NULL;
|
| + return ExecuteScriptAndParse(
|
| + frame_id,
|
| + "function(elem) { return elem.tagName.toLowerCase() }",
|
| + "getElementTagName",
|
| + CreateListValueFrom(element),
|
| + CreateDirectValueParser(tag_name));
|
| }
|
|
|
| Error* Session::GetClickableLocation(const WebElementId& element,
|
| - gfx::Point* location) {
|
| + Point* location) {
|
| bool is_displayed = false;
|
| Error* error = IsElementDisplayed(
|
| current_target_, element, true /* ignore_opacity */, &is_displayed);
|
| @@ -1019,7 +918,7 @@ Error* Session::GetClickableLocation(const WebElementId& element,
|
| if (!is_displayed)
|
| return new Error(kElementNotVisible, "Element must be displayed to click");
|
|
|
| - gfx::Rect rect;
|
| + Rect rect;
|
| error = GetElementFirstClientRect(current_target_, element, &rect);
|
| if (error)
|
| return error;
|
| @@ -1034,20 +933,13 @@ Error* Session::GetClickableLocation(const WebElementId& element,
|
| }
|
|
|
| Error* Session::GetAttribute(const WebElementId& element,
|
| - const std::string& key, Value** value) {
|
| - std::string script = base::StringPrintf(
|
| - "return (%s).apply(null, arguments);", atoms::GET_ATTRIBUTE);
|
| -
|
| - ListValue args;
|
| - args.Append(element.ToValue());
|
| - args.Append(Value::CreateStringValue(key));
|
| -
|
| - Error* error = ExecuteScript(script, &args, value);
|
| - if (error) {
|
| - return error;
|
| - }
|
| -
|
| - return NULL;
|
| + const std::string& key,
|
| + Value** value) {
|
| + return ExecuteScriptAndParse(current_target_,
|
| + atoms::GET_ATTRIBUTE,
|
| + "getAttribute",
|
| + CreateListValueFrom(element, key),
|
| + CreateDirectValueParser(value));
|
| }
|
|
|
| Error* Session::WaitForAllTabsToStopLoading() {
|
| @@ -1095,7 +987,7 @@ int Session::implicit_wait() const {
|
| return implicit_wait_;
|
| }
|
|
|
| -const gfx::Point& Session::get_mouse_position() const {
|
| +const Point& Session::get_mouse_position() const {
|
| return mouse_position_;
|
| }
|
|
|
| @@ -1145,9 +1037,9 @@ void Session::TerminateOnSessionThread() {
|
| automation_.reset();
|
| }
|
|
|
| -Error* Session::ExecuteScriptAndParseResponse(const FrameId& frame_id,
|
| - const std::string& script,
|
| - Value** script_result) {
|
| +Error* Session::ExecuteScriptAndParseValue(const FrameId& frame_id,
|
| + const std::string& script,
|
| + Value** script_result) {
|
| std::string response_json;
|
| Error* error = NULL;
|
| RunSessionTask(NewRunnableMethod(
|
| @@ -1236,31 +1128,43 @@ void Session::SendKeysOnSessionThread(const string16& keys, Error** error) {
|
|
|
| Error* Session::SwitchToFrameWithJavaScriptLocatedFrame(
|
| const std::string& script, ListValue* args) {
|
| - Value* unscoped_result = NULL;
|
| - Error* error = ExecuteScript(script, args, &unscoped_result);
|
| - scoped_ptr<Value> result(unscoped_result);
|
| + class SwitchFrameValueParser : public ValueParser {
|
| + public:
|
| + SwitchFrameValueParser(
|
| + bool* found_frame, WebElementId* frame, std::string* xpath)
|
| + : found_frame_(found_frame), frame_(frame), xpath_(xpath) { }
|
| +
|
| + virtual ~SwitchFrameValueParser() { }
|
| +
|
| + virtual bool Parse(base::Value* value) const OVERRIDE {
|
| + if (value->IsType(Value::TYPE_NULL)) {
|
| + *found_frame_ = false;
|
| + return true;
|
| + }
|
| + ListValue* list;
|
| + if (!value->GetAsList(&list))
|
| + return false;
|
| + *found_frame_ = true;
|
| + return SetFromListValue(list, frame_, xpath_);
|
| + }
|
| +
|
| + private:
|
| + bool* found_frame_;
|
| + WebElementId* frame_;
|
| + std::string* xpath_;
|
| + };
|
| +
|
| + bool found_frame;
|
| + WebElementId new_frame_element;
|
| + std::string xpath;
|
| + Error* error = ExecuteScriptAndParse(
|
| + current_target_, script, "switchFrame", args,
|
| + new SwitchFrameValueParser(&found_frame, &new_frame_element, &xpath));
|
| if (error)
|
| return error;
|
|
|
| - ListValue* frame_and_xpath_list;
|
| - if (!result->GetAsList(&frame_and_xpath_list))
|
| + if (!found_frame)
|
| return new Error(kNoSuchFrame);
|
| - DictionaryValue* element_dict;
|
| - std::string xpath;
|
| - if (!frame_and_xpath_list->GetDictionary(0, &element_dict) ||
|
| - !frame_and_xpath_list->GetString(1, &xpath)) {
|
| - return new Error(
|
| - kUnknownError,
|
| - "Frame finding script did not return correct type: " +
|
| - JsonStringify(frame_and_xpath_list));
|
| - }
|
| - WebElementId new_frame_element(element_dict);
|
| - if (!new_frame_element.is_valid()) {
|
| - return new Error(
|
| - kUnknownError,
|
| - "Frame finding script did not return a frame element: " +
|
| - JsonStringify(element_dict));
|
| - }
|
|
|
| frame_elements_.push_back(new_frame_element);
|
| current_target_.frame_path = current_target_.frame_path.Append(xpath);
|
| @@ -1274,132 +1178,143 @@ Error* Session::FindElementsHelper(const FrameId& frame_id,
|
| bool find_one,
|
| std::vector<WebElementId>* elements) {
|
| CHECK(root_element.is_valid());
|
| -
|
| - std::string jscript;
|
| - if (find_one) {
|
| - // TODO(jleyba): Write a Chrome-specific find element atom that will
|
| - // correctly throw an error if the element cannot be found.
|
| - jscript = base::StringPrintf(
|
| - "var result = (%s).apply(null, arguments);"
|
| - "if (!result) {"
|
| - "var e = new Error('Unable to locate element');"
|
| - "e.code = %d;"
|
| - "throw e;"
|
| - "} else { return result; }",
|
| - atoms::FIND_ELEMENT, kNoSuchElement);
|
| - } else {
|
| - jscript = base::StringPrintf("return (%s).apply(null, arguments);",
|
| - atoms::FIND_ELEMENTS);
|
| - }
|
| - ListValue jscript_args;
|
| - DictionaryValue* locator_dict = new DictionaryValue();
|
| - locator_dict->SetString(locator, query);
|
| - jscript_args.Append(locator_dict);
|
| - jscript_args.Append(root_element.ToValue());
|
| -
|
| - // The element search needs to loop until at least one element is found or the
|
| - // session's implicit wait timeout expires, whichever occurs first.
|
| base::Time start_time = base::Time::Now();
|
| + while (true) {
|
| + std::vector<WebElementId> temp_elements;
|
| + Error* error = ExecuteFindElementScriptAndParse(
|
| + frame_id, root_element, locator, query, find_one, &temp_elements);
|
| + if (error)
|
| + return error;
|
|
|
| - scoped_ptr<Value> value;
|
| - scoped_ptr<Error> error;
|
| - bool done = false;
|
| - while (!done) {
|
| - Value* unscoped_value = NULL;
|
| - error.reset(ExecuteScript(
|
| - frame_id, jscript, &jscript_args, &unscoped_value));
|
| - value.reset(unscoped_value);
|
| - if (!error.get()) {
|
| - // If searching for many elements, make sure we found at least one before
|
| - // stopping.
|
| - done = find_one ||
|
| - (value->GetType() == Value::TYPE_LIST &&
|
| - static_cast<ListValue*>(value.get())->GetSize() > 0);
|
| - } else if (error->code() != kNoSuchElement) {
|
| - return error.release();
|
| + if (temp_elements.size() > 0u) {
|
| + elements->swap(temp_elements);
|
| + break;
|
| + }
|
| +
|
| + if ((base::Time::Now() - start_time).InMilliseconds() > implicit_wait_) {
|
| + if (find_one)
|
| + return new Error(kNoSuchElement);
|
| + break;
|
| }
|
| - int64 elapsed_time = (base::Time::Now() - start_time).InMilliseconds();
|
| - done = done || elapsed_time > implicit_wait_;
|
| - if (!done)
|
| - base::PlatformThread::Sleep(50); // Prevent a busy loop.
|
| + base::PlatformThread::Sleep(50);
|
| }
|
| + return NULL;
|
| +}
|
|
|
| - if (error.get())
|
| - return error.release();
|
| -
|
| - // Parse the results.
|
| - const std::string kInvalidElementDictionaryMessage =
|
| - "Find element script returned invalid element dictionary: " +
|
| - JsonStringify(value.get());
|
| - if (value->IsType(Value::TYPE_LIST)) {
|
| - ListValue* element_list = static_cast<ListValue*>(value.get());
|
| - for (size_t i = 0; i < element_list->GetSize(); ++i) {
|
| - DictionaryValue* element_dict = NULL;
|
| - if (!element_list->GetDictionary(i, &element_dict)) {
|
| - return new Error(
|
| - kUnknownError,
|
| - "Find element script returned non-dictionary: " +
|
| - JsonStringify(element_list));
|
| - }
|
| +Error* Session::ExecuteFindElementScriptAndParse(
|
| + const FrameId& frame_id,
|
| + const WebElementId& root_element,
|
| + const std::string& locator,
|
| + const std::string& query,
|
| + bool find_one,
|
| + std::vector<WebElementId>* elements) {
|
| + CHECK(root_element.is_valid());
|
|
|
| - WebElementId element(element_dict);
|
| - if (!element.is_valid()) {
|
| - return new Error(kUnknownError, kInvalidElementDictionaryMessage);
|
| + class FindElementsParser : public ValueParser {
|
| + public:
|
| + explicit FindElementsParser(std::vector<WebElementId>* elements)
|
| + : elements_(elements) { }
|
| +
|
| + virtual ~FindElementsParser() { }
|
| +
|
| + virtual bool Parse(base::Value* value) const OVERRIDE {
|
| + if (!value->IsType(Value::TYPE_LIST))
|
| + return false;
|
| + ListValue* list = static_cast<ListValue*>(value);
|
| + for (size_t i = 0; i < list->GetSize(); ++i) {
|
| + WebElementId element;
|
| + Value* element_value = NULL;
|
| + if (!list->Get(i, &element_value))
|
| + return false;
|
| + if (!SetFromValue(element_value, &element))
|
| + return false;
|
| + elements_->push_back(element);
|
| }
|
| - elements->push_back(element);
|
| + return true;
|
| }
|
| - } else if (value->IsType(Value::TYPE_DICTIONARY)) {
|
| - DictionaryValue* element_dict =
|
| - static_cast<DictionaryValue*>(value.get());
|
| - WebElementId element(element_dict);
|
| - if (!element.is_valid()) {
|
| - return new Error(kUnknownError, kInvalidElementDictionaryMessage);
|
| + private:
|
| + std::vector<WebElementId>* elements_;
|
| + };
|
| +
|
| + class FindElementParser : public ValueParser {
|
| + public:
|
| + explicit FindElementParser(std::vector<WebElementId>* elements)
|
| + : elements_(elements) { }
|
| +
|
| + virtual ~FindElementParser() { }
|
| +
|
| + virtual bool Parse(base::Value* value) const OVERRIDE {
|
| + if (value->IsType(Value::TYPE_NULL))
|
| + return true;
|
| + WebElementId element;
|
| + bool set = SetFromValue(value, &element);
|
| + if (set)
|
| + elements_->push_back(element);
|
| + return set;
|
| }
|
| - elements->push_back(element);
|
| + private:
|
| + std::vector<WebElementId>* elements_;
|
| + };
|
| +
|
| + DictionaryValue locator_dict;
|
| + locator_dict.SetString(locator, query);
|
| + std::vector<WebElementId> temp_elements;
|
| + Error* error = NULL;
|
| + if (find_one) {
|
| + error = ExecuteScriptAndParse(
|
| + frame_id,
|
| + atoms::FIND_ELEMENT,
|
| + "findElement",
|
| + CreateListValueFrom(&locator_dict, root_element),
|
| + new FindElementParser(&temp_elements));
|
| } else {
|
| - return new Error(
|
| - kUnknownError,
|
| - "Find element script returned unsupported type: " +
|
| - JsonStringify(value.get()));
|
| + error = ExecuteScriptAndParse(
|
| + frame_id,
|
| + atoms::FIND_ELEMENTS,
|
| + "findElements",
|
| + CreateListValueFrom(&locator_dict, root_element),
|
| + new FindElementsParser(&temp_elements));
|
| }
|
| - return NULL;
|
| + if (!error)
|
| + elements->swap(temp_elements);
|
| + return error;
|
| }
|
|
|
| Error* Session::VerifyElementIsClickable(
|
| const FrameId& frame_id,
|
| const WebElementId& element,
|
| - const gfx::Point& location) {
|
| - std::string jscript = base::StringPrintf(
|
| - "return (%s).apply(null, arguments);", atoms::IS_ELEMENT_CLICKABLE);
|
| - ListValue jscript_args;
|
| - jscript_args.Append(element.ToValue());
|
| - DictionaryValue* location_dict = new DictionaryValue();
|
| - location_dict->SetInteger("x", location.x());
|
| - location_dict->SetInteger("y", location.y());
|
| - jscript_args.Append(location_dict);
|
| - Value* unscoped_value = NULL;
|
| - Error* error = ExecuteScript(frame_id, jscript, &jscript_args,
|
| - &unscoped_value);
|
| + const Point& location) {
|
| + class IsElementClickableParser : public ValueParser {
|
| + public:
|
| + IsElementClickableParser(bool* clickable, std::string* message)
|
| + : clickable_(clickable), message_(message) { }
|
| +
|
| + virtual ~IsElementClickableParser() { }
|
| +
|
| + virtual bool Parse(base::Value* value) const OVERRIDE {
|
| + if (!value->IsType(Value::TYPE_DICTIONARY))
|
| + return false;
|
| + DictionaryValue* dict = static_cast<DictionaryValue*>(value);
|
| + dict->GetString("message", message_);
|
| + return dict->GetBoolean("clickable", clickable_);
|
| + }
|
| +
|
| + private:
|
| + bool* clickable_;
|
| + std::string* message_;
|
| + };
|
| +
|
| + bool clickable;
|
| + std::string message;
|
| + Error* error = ExecuteScriptAndParse(
|
| + frame_id,
|
| + atoms::IS_ELEMENT_CLICKABLE,
|
| + "isElementClickable",
|
| + CreateListValueFrom(element, location),
|
| + new IsElementClickableParser(&clickable, &message));
|
| if (error)
|
| return error;
|
|
|
| - scoped_ptr<Value> value(unscoped_value);
|
| - if (!value->IsType(Value::TYPE_DICTIONARY)) {
|
| - return new Error(
|
| - kUnknownError,
|
| - "isElementClickable atom returned non-dictionary type: " +
|
| - JsonStringify(value.get()));
|
| - }
|
| - DictionaryValue* dict = static_cast<DictionaryValue*>(value.get());
|
| - bool clickable = false;
|
| - if (!dict->GetBoolean("clickable", &clickable)) {
|
| - return new Error(
|
| - kUnknownError,
|
| - "isElementClickable atom returned bad invalid dictionary: " +
|
| - JsonStringify(dict));
|
| - }
|
| - std::string message;
|
| - dict->GetString("message", &message);
|
| if (!clickable) {
|
| if (message.empty())
|
| message = "element is not clickable";
|
| @@ -1414,47 +1329,20 @@ Error* Session::VerifyElementIsClickable(
|
| Error* Session::GetElementRegionInViewHelper(
|
| const FrameId& frame_id,
|
| const WebElementId& element,
|
| - const gfx::Rect& region,
|
| + const Rect& region,
|
| bool center,
|
| bool verify_clickable_at_middle,
|
| - gfx::Point* location) {
|
| - std::string jscript = base::StringPrintf(
|
| - "return (%s).apply(null, arguments);", atoms::GET_LOCATION_IN_VIEW);
|
| - ListValue jscript_args;
|
| - jscript_args.Append(element.ToValue());
|
| - jscript_args.Append(Value::CreateBooleanValue(center));
|
| - DictionaryValue* elem_offset_dict = new DictionaryValue();
|
| - elem_offset_dict->SetInteger("left", region.x());
|
| - elem_offset_dict->SetInteger("top", region.y());
|
| - elem_offset_dict->SetInteger("width", region.width());
|
| - elem_offset_dict->SetInteger("height", region.height());
|
| - jscript_args.Append(elem_offset_dict);
|
| - Value* unscoped_value = NULL;
|
| - Error* error = ExecuteScript(frame_id, jscript, &jscript_args,
|
| - &unscoped_value);
|
| - scoped_ptr<Value> value(unscoped_value);
|
| - if (error)
|
| - return error;
|
| -
|
| - if (!value->IsType(Value::TYPE_DICTIONARY)) {
|
| - return new Error(
|
| - kUnknownError,
|
| - "Location atom returned non-dictionary type: " +
|
| - JsonStringify(value.get()));
|
| - }
|
| - DictionaryValue* loc_dict = static_cast<DictionaryValue*>(value.get());
|
| - int x = 0, y = 0;
|
| - if (!loc_dict->GetInteger("x", &x) ||
|
| - !loc_dict->GetInteger("y", &y)) {
|
| - return new Error(
|
| - kUnknownError,
|
| - "Location atom returned bad coordinate dictionary: " +
|
| - JsonStringify(loc_dict));
|
| - }
|
| - gfx::Point temp_location = gfx::Point(x, y);
|
| + Point* location) {
|
| + Point temp_location;
|
| + Error* error = ExecuteScriptAndParse(
|
| + frame_id,
|
| + atoms::GET_LOCATION_IN_VIEW,
|
| + "getLocationInView",
|
| + CreateListValueFrom(element, center, region),
|
| + CreateDirectValueParser(&temp_location));
|
|
|
| if (verify_clickable_at_middle) {
|
| - gfx::Point middle_point = temp_location;
|
| + Point middle_point = temp_location;
|
| middle_point.Offset(region.width() / 2, region.height() / 2);
|
| error = VerifyElementIsClickable(frame_id, element, middle_point);
|
| if (error)
|
| @@ -1487,39 +1375,21 @@ Error* Session::GetScreenShot(std::string* png) {
|
| }
|
|
|
| Error* Session::GetBrowserConnectionState(bool* online) {
|
| - std::string jscript = base::StringPrintf(
|
| - "return (%s).apply(null, arguments);", atoms::IS_ONLINE);
|
| - base::ListValue no_args;
|
| - Value* unscoped_value = NULL;
|
| - Error* error = ExecuteScript(jscript,
|
| - &no_args,
|
| - &unscoped_value);
|
| - scoped_ptr<base::Value> value(unscoped_value);
|
| - if (error)
|
| - return error;
|
| - if (!value->GetAsBoolean(online))
|
| - return new Error(kUnknownError,
|
| - "IS_ONLINE script returned non-boolean: " +
|
| - JsonStringify(value.get()));
|
| - return NULL;
|
| + return ExecuteScriptAndParse(
|
| + current_target_,
|
| + atoms::IS_ONLINE,
|
| + "isOnline",
|
| + new ListValue(),
|
| + CreateDirectValueParser(online));
|
| }
|
|
|
| Error* Session::GetAppCacheStatus(int* status) {
|
| - std::string jscript = base::StringPrintf(
|
| - "return (%s).apply(null, arguments);", atoms::GET_APPCACHE_STATUS);
|
| - base::ListValue no_args;
|
| - Value* unscoped_value = NULL;
|
| - Error* error = ExecuteScript(jscript,
|
| - &no_args,
|
| - &unscoped_value);
|
| - scoped_ptr<base::Value> value(unscoped_value);
|
| - if (error)
|
| - return error;
|
| - if (!value->GetAsInteger(status))
|
| - return new Error(kUnknownError,
|
| - "GET_APPCACHE_STATUS script returned non-integer: " +
|
| - JsonStringify(value.get()));
|
| - return NULL;
|
| + return ExecuteScriptAndParse(
|
| + current_target_,
|
| + atoms::GET_APPCACHE_STATUS,
|
| + "getAppcacheStatus",
|
| + new ListValue(),
|
| + CreateDirectValueParser(status));
|
| }
|
|
|
| } // namespace webdriver
|
|
|