// 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. #include "chrome/test/automation/dom_element_proxy.h" #include "chrome/test/automation/javascript_execution_controller.h" #include "chrome/test/automation/javascript_message_utils.h" #include "testing/gtest/include/gtest/gtest.h" using javascript_utils::JavaScriptPrintf; // JavaScriptObjectProxy methods JavaScriptObjectProxy::JavaScriptObjectProxy( JavaScriptExecutionController* executor, int handle) : executor_(executor->AsWeakPtr()), handle_(handle) {} JavaScriptObjectProxy::~JavaScriptObjectProxy() { if (is_valid()) executor_->Remove(handle_); } // DOMElementProxy::By methods // static DOMElementProxy::By DOMElementProxy::By::XPath( const std::string& xpath) { return By(TYPE_XPATH, xpath); } // static DOMElementProxy::By DOMElementProxy::By::Selectors( const std::string& selectors) { return By(TYPE_SELECTORS, selectors); } // static DOMElementProxy::By DOMElementProxy::By::Text( const std::string& text) { return By(TYPE_TEXT, text); } // DOMElementProxy methods DOMElementProxyRef DOMElementProxy::GetContentDocument() { int element_handle; if (!GetValue("contentdocument", &element_handle)) return NULL; return executor_->GetObjectProxy(element_handle); } DOMElementProxyRef DOMElementProxy::GetDocumentFromFrame( const std::vector& frame_names) { if (!is_valid()) return NULL; const char* script = "domAutomation.getDocumentFromFrame(" "domAutomation.getObject(%s), %s);"; int element_handle; if (!executor_->ExecuteJavaScriptAndGetReturn( JavaScriptPrintf(script, this->handle(), frame_names), &element_handle)) { return NULL; } return executor_->GetObjectProxy(element_handle); } DOMElementProxyRef DOMElementProxy::GetDocumentFromFrame( const std::string& frame_name1, const std::string& frame_name2, const std::string& frame_name3) { if (!is_valid()) return NULL; std::vector frame_names; frame_names.push_back(frame_name1); if (!frame_name2.empty()) frame_names.push_back(frame_name2); if (!frame_name3.empty()) frame_names.push_back(frame_name3); return GetDocumentFromFrame(frame_names); } DOMElementProxyRef DOMElementProxy::FindElement(const By& by) { if (!is_valid()) return NULL; const char* script = "domAutomation.findElement(" "domAutomation.getObject(%s), %s);"; int element_handle; if (!executor_->ExecuteJavaScriptAndGetReturn( JavaScriptPrintf(script, this->handle(), by), &element_handle)) { return NULL; } return executor_->GetObjectProxy(element_handle); } bool DOMElementProxy::FindElements(const By& by, std::vector* elements) { if (!elements) { NOTREACHED(); return false; } if (!is_valid()) return false; const char* script = "domAutomation.findElements(" "domAutomation.getObject(%s), %s);"; std::vector element_handles; if (!executor_->ExecuteJavaScriptAndGetReturn( JavaScriptPrintf(script, this->handle(), by), &element_handles)) { return false; } for (size_t i = 0; i < element_handles.size(); i++) { elements->push_back(make_scoped_refptr( executor_->GetObjectProxy(element_handles[i]))); } return true; } bool DOMElementProxy::WaitForVisibleElementCount( const By& by, int count, std::vector* elements) { if (!elements) { NOTREACHED(); return false; } if (!is_valid()) return false; const char* script = "domAutomation.waitForVisibleElementCount(" "domAutomation.getObject(%s), %s, %s," "domAutomation.getCallId());"; std::vector element_handles; if (!executor_->ExecuteAsyncJavaScriptAndGetReturn( JavaScriptPrintf(script, this->handle(), by, count), &element_handles)) { return false; } if (static_cast(element_handles.size()) == count) { for (size_t i = 0; i < element_handles.size(); i++) { elements->push_back(make_scoped_refptr( executor_->GetObjectProxy(element_handles[i]))); } } return static_cast(element_handles.size()) == count; } DOMElementProxyRef DOMElementProxy::WaitFor1VisibleElement(const By& by) { std::vector elements; if (!WaitForVisibleElementCount(by, 1, &elements)) return NULL; return elements[0]; } bool DOMElementProxy::WaitForElementsToDisappear(const By& by) { std::vector elements; return WaitForVisibleElementCount(by, 0, &elements); } bool DOMElementProxy::Click() { if (!is_valid()) return false; const char* script = "domAutomation.click(domAutomation.getObject(%s));"; return executor_->ExecuteJavaScript( JavaScriptPrintf(script, this->handle())); } bool DOMElementProxy::Type(const std::string& text) { if (!is_valid()) return false; const char* script = "domAutomation.type(domAutomation.getObject(%s), %s);"; bool success = false; if (!executor_->ExecuteJavaScriptAndGetReturn( JavaScriptPrintf(script, this->handle(), text), &success)) { return false; } return success; } bool DOMElementProxy::SetText(const std::string& text) { if (!is_valid()) return false; const char* script = "domAutomation.setText(" "domAutomation.getObject(%s), %s);"; bool success = false; if (!executor_->ExecuteJavaScriptAndGetReturn( JavaScriptPrintf(script, this->handle(), text), &success)) { return false; } return success; } bool DOMElementProxy::GetProperty(const std::string& property, std::string* out) { if (!out) { NOTREACHED(); return false; } if (!is_valid()) return false; const char* script = "domAutomation.getProperty(" "domAutomation.getObject(%s), %s);"; return executor_->ExecuteJavaScriptAndGetReturn( JavaScriptPrintf(script, this->handle(), property), out); } bool DOMElementProxy::GetAttribute(const std::string& attribute, std::string* out) { if (!out) { NOTREACHED(); return false; } if (!is_valid()) return false; const char* script = "domAutomation.getAttribute(" "domAutomation.getObject(%s), %s);"; return executor_->ExecuteJavaScriptAndGetReturn( JavaScriptPrintf(script, this->handle(), attribute), out); } bool DOMElementProxy::GetText(std::string* text) { return GetValue("text", text); } bool DOMElementProxy::GetInnerHTML(std::string* html) { return GetValue("innerhtml", html); } bool DOMElementProxy::GetId(std::string* id) { return GetValue("id", id); } bool DOMElementProxy::GetName(std::string* name) { return GetAttribute("name", name); } bool DOMElementProxy::GetVisibility(bool* visibility) { return GetValue("visibility", visibility); } void DOMElementProxy::EnsureFindNoElements(const By& by) { std::vector elements; ASSERT_TRUE(FindElements(by, &elements)); ASSERT_EQ(0u, elements.size()); } void DOMElementProxy::EnsureTextMatches(const std::string& expected_text) { std::string text; ASSERT_TRUE(GetText(&text)); ASSERT_EQ(expected_text, text); } void DOMElementProxy::EnsureInnerHTMLMatches(const std::string& expected_html) { std::string html; ASSERT_TRUE(GetInnerHTML(&html)); ASSERT_EQ(expected_html, html); } void DOMElementProxy::EnsureNameMatches(const std::string& expected_name) { std::string name; ASSERT_TRUE(GetName(&name)); ASSERT_EQ(expected_name, name); } void DOMElementProxy::EnsureVisibilityMatches(bool expected_visibility) { bool visibility; ASSERT_TRUE(GetVisibility(&visibility)); ASSERT_EQ(expected_visibility, visibility); } void DOMElementProxy::EnsureAttributeEventuallyMatches( const std::string& attribute, const std::string& new_value) { ASSERT_TRUE(is_valid()); const char* script = "domAutomation.waitForAttribute(" "domAutomation.getObject(%s), %s, %s," "domAutomation.getCallId())"; if (!executor_->ExecuteAsyncJavaScript( JavaScriptPrintf(script, this->handle(), attribute, new_value))) { FAIL() << "Executing or parsing JavaScript failed"; } } template bool DOMElementProxy::GetValue(const std::string& type, T* value) { if (!value) { NOTREACHED(); return false; } if (!is_valid()) return false; const char* script = "domAutomation.getValue(" "domAutomation.getObject(%s), %s);"; return executor_->ExecuteJavaScriptAndGetReturn( JavaScriptPrintf(script, this->handle(), type), value); }