blob: e8c623bc60616e0273d80194f6f19cd51d06a5e8 [file] [log] [blame]
// Copyright (c) 2011 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 "base/memory/ref_counted.h"
#include "base/string_number_conversions.h"
#include "base/utf_string_conversions.h"
#include "chrome/test/automation/dom_element_proxy.h"
#include "chrome/test/automation/javascript_execution_controller.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
namespace {
// Tests the DOMAutomation framework for manipulating DOMElements within
// browser tests.
class DOMAutomationTest : public InProcessBrowserTest {
public:
DOMAutomationTest() {
EnableDOMAutomation();
JavaScriptExecutionController::set_timeout(30000);
}
GURL GetTestURL(const char* path) {
std::string url_path = "files/dom_automation/";
url_path.append(path);
return test_server()->GetURL(url_path);
}
};
typedef DOMElementProxy::By By;
#if defined(OS_WIN)
// See http://crbug.com/61636
#define MAYBE_FindByXPath DISABLED_FindByXPath
#else
#define MAYBE_FindByXPath FindByXPath
#endif
IN_PROC_BROWSER_TEST_F(DOMAutomationTest, MAYBE_FindByXPath) {
ASSERT_TRUE(test_server()->Start());
ui_test_utils::NavigateToURL(browser(),
GetTestURL("find_elements/test.html"));
DOMElementProxyRef main_doc = ui_test_utils::GetActiveDOMDocument(browser());
// Find first element.
DOMElementProxyRef first_div = main_doc->FindElement(By::XPath("//div"));
ASSERT_TRUE(first_div);
ASSERT_NO_FATAL_FAILURE(first_div->EnsureNameMatches("0"));
// Find many elements.
std::vector<DOMElementProxyRef> elements;
ASSERT_TRUE(main_doc->FindElements(By::XPath("//div"), &elements));
ASSERT_EQ(2u, elements.size());
for (size_t i = 0; i < elements.size(); i++) {
ASSERT_NO_FATAL_FAILURE(elements[i]->EnsureNameMatches(
base::UintToString(i)));
}
// Find 0 elements.
ASSERT_FALSE(main_doc->FindElement(By::XPath("//nosuchtag")));
elements.clear();
ASSERT_TRUE(main_doc->FindElements(By::XPath("//nosuchtag"), &elements));
elements.clear();
ASSERT_EQ(0u, elements.size());
// Find with invalid xpath.
ASSERT_FALSE(main_doc->FindElement(By::XPath("'invalid'")));
ASSERT_FALSE(main_doc->FindElement(By::XPath(" / / ")));
ASSERT_FALSE(main_doc->FindElements(By::XPath("'invalid'"), &elements));
ASSERT_FALSE(main_doc->FindElements(By::XPath(" / / "), &elements));
// Find nested elements.
int nested_count = 0;
std::string span_name;
DOMElementProxyRef node = main_doc->FindElement(By::XPath("/html/body/span"));
while (node) {
nested_count++;
span_name.append("span");
ASSERT_NO_FATAL_FAILURE(node->EnsureNameMatches(span_name));
node = node->FindElement(By::XPath("./span"));
}
ASSERT_EQ(3, nested_count);
}
IN_PROC_BROWSER_TEST_F(DOMAutomationTest, FindBySelectors) {
ASSERT_TRUE(test_server()->Start());
ui_test_utils::NavigateToURL(browser(),
GetTestURL("find_elements/test.html"));
DOMElementProxyRef main_doc = ui_test_utils::GetActiveDOMDocument(browser());
// Find first element.
DOMElementProxyRef first_myclass =
main_doc->FindElement(By::Selectors(".myclass"));
ASSERT_TRUE(first_myclass);
ASSERT_NO_FATAL_FAILURE(first_myclass->EnsureNameMatches("0"));
// Find many elements.
std::vector<DOMElementProxyRef> elements;
ASSERT_TRUE(main_doc->FindElements(By::Selectors(".myclass"), &elements));
ASSERT_EQ(2u, elements.size());
for (size_t i = 0; i < elements.size(); i++) {
ASSERT_NO_FATAL_FAILURE(elements[i]->EnsureNameMatches(
base::UintToString(i)));
}
// Find 0 elements.
ASSERT_FALSE(main_doc->FindElement(By::Selectors("#nosuchid")));
elements.clear();
ASSERT_TRUE(main_doc->FindElements(By::Selectors("#nosuchid"), &elements));
ASSERT_EQ(0u, elements.size());
// Find with invalid selectors.
ASSERT_FALSE(main_doc->FindElement(By::Selectors("1#2")));
ASSERT_FALSE(main_doc->FindElements(By::Selectors("1#2"), &elements));
// Find nested elements.
int nested_count = 0;
std::string span_name;
DOMElementProxyRef node = main_doc->FindElement(By::Selectors("span"));
while (node) {
nested_count++;
span_name.append("span");
ASSERT_NO_FATAL_FAILURE(node->EnsureNameMatches(span_name));
node = node->FindElement(By::Selectors("span"));
}
ASSERT_EQ(3, nested_count);
}
#if defined(OS_WIN)
// http://crbug.com/72745
#define MAYBE_FindByText FLAKY_FindByText
#else
#define MAYBE_FindByText FindByText
#endif
IN_PROC_BROWSER_TEST_F(DOMAutomationTest, MAYBE_FindByText) {
ASSERT_TRUE(test_server()->Start());
ui_test_utils::NavigateToURL(browser(),
GetTestURL("find_elements/test.html"));
DOMElementProxyRef main_doc = ui_test_utils::GetActiveDOMDocument(browser());
// Find first element.
DOMElementProxyRef first_text = main_doc->FindElement(By::Text("div_text"));
ASSERT_TRUE(first_text);
ASSERT_NO_FATAL_FAILURE(first_text->EnsureNameMatches("0"));
// Find many elements.
std::vector<DOMElementProxyRef> elements;
ASSERT_TRUE(main_doc->FindElements(By::Text("div_text"), &elements));
ASSERT_EQ(2u, elements.size());
for (size_t i = 0; i < elements.size(); i++) {
ASSERT_NO_FATAL_FAILURE(elements[i]->EnsureNameMatches(
base::UintToString(i)));
}
// Find 0 elements.
ASSERT_FALSE(main_doc->FindElement(By::Text("nosuchtext")));
elements.clear();
ASSERT_TRUE(main_doc->FindElements(By::Text("nosuchtext"), &elements));
ASSERT_EQ(0u, elements.size());
// Find nested elements.
int nested_count = 0;
std::string span_name;
DOMElementProxyRef node = main_doc->FindElement(By::Text("span_text"));
while (node) {
nested_count++;
span_name.append("span");
ASSERT_NO_FATAL_FAILURE(node->EnsureNameMatches(span_name));
node = node->FindElement(By::Text("span_text"));
}
ASSERT_EQ(3, nested_count);
// Find only visible text.
DOMElementProxyRef shown_td = main_doc->FindElement(By::Text("table_text"));
ASSERT_TRUE(shown_td);
ASSERT_NO_FATAL_FAILURE(shown_td->EnsureNameMatches("shown"));
// Find text in inputs.
ASSERT_TRUE(main_doc->FindElement(By::Text("textarea_text")));
ASSERT_TRUE(main_doc->FindElement(By::Text("input_text")));
}
IN_PROC_BROWSER_TEST_F(DOMAutomationTest, WaitFor1VisibleElement) {
ASSERT_TRUE(test_server()->Start());
ui_test_utils::NavigateToURL(browser(), GetTestURL("wait/test.html"));
DOMElementProxyRef main_doc = ui_test_utils::GetActiveDOMDocument(browser());
DOMElementProxyRef div =
main_doc->WaitFor1VisibleElement(By::Selectors("div"));
ASSERT_TRUE(div.get());
ASSERT_NO_FATAL_FAILURE(div->EnsureInnerHTMLMatches("div_inner"));
}
IN_PROC_BROWSER_TEST_F(DOMAutomationTest, WaitForElementsToDisappear) {
ASSERT_TRUE(test_server()->Start());
ui_test_utils::NavigateToURL(browser(), GetTestURL("wait/test.html"));
DOMElementProxyRef main_doc = ui_test_utils::GetActiveDOMDocument(browser());
ASSERT_TRUE(main_doc->WaitForElementsToDisappear(By::Selectors("img")));
std::vector<DOMElementProxyRef> img_elements;
ASSERT_TRUE(main_doc->FindElements(By::Selectors("img"), &img_elements));
ASSERT_EQ(0u, img_elements.size());
}
IN_PROC_BROWSER_TEST_F(DOMAutomationTest, EnsureAttributeEventuallyMatches) {
ASSERT_TRUE(test_server()->Start());
ui_test_utils::NavigateToURL(browser(), GetTestURL("wait/test.html"));
DOMElementProxyRef main_doc = ui_test_utils::GetActiveDOMDocument(browser());
DOMElementProxyRef anchor = main_doc->FindElement(By::Selectors("a"));
ASSERT_TRUE(anchor.get());
ASSERT_NO_FATAL_FAILURE(anchor->EnsureAttributeEventuallyMatches(
"href", "http://www.google.com"));
}
IN_PROC_BROWSER_TEST_F(DOMAutomationTest, Frames) {
ASSERT_TRUE(test_server()->Start());
ui_test_utils::NavigateToURL(browser(), GetTestURL("frames/test.html"));
DOMElementProxyRef main_doc = ui_test_utils::GetActiveDOMDocument(browser());
// Get both frame elements.
std::vector<DOMElementProxyRef> frame_elements;
ASSERT_TRUE(main_doc->FindElements(By::XPath("//frame"), &frame_elements));
ASSERT_EQ(2u, frame_elements.size());
// Get both frames, checking their contents are correct.
DOMElementProxyRef frame1 = frame_elements[0]->GetContentDocument();
DOMElementProxyRef frame2 = frame_elements[1]->GetContentDocument();
ASSERT_TRUE(frame1 && frame2);
DOMElementProxyRef frame_div =
frame1->FindElement(By::XPath("/html/body/div"));
ASSERT_TRUE(frame_div);
ASSERT_NO_FATAL_FAILURE(frame_div->EnsureInnerHTMLMatches("frame 1"));
frame_div = frame2->FindElement(By::XPath("/html/body/div"));
ASSERT_TRUE(frame_div);
ASSERT_NO_FATAL_FAILURE(frame_div->EnsureInnerHTMLMatches("frame 2"));
// Get both inner iframes, checking their contents are correct.
DOMElementProxyRef iframe1 =
frame1->GetDocumentFromFrame("0");
DOMElementProxyRef iframe2 =
frame2->GetDocumentFromFrame("0");
ASSERT_TRUE(iframe1 && iframe2);
frame_div = iframe1->FindElement(By::XPath("/html/body/div"));
ASSERT_TRUE(frame_div);
ASSERT_NO_FATAL_FAILURE(frame_div->EnsureInnerHTMLMatches("iframe 1"));
frame_div = iframe2->FindElement(By::XPath("/html/body/div"));
ASSERT_TRUE(frame_div);
ASSERT_NO_FATAL_FAILURE(frame_div->EnsureInnerHTMLMatches("iframe 2"));
// Get nested frame.
ASSERT_EQ(iframe1.get(), main_doc->GetDocumentFromFrame("0", "0").get());
ASSERT_EQ(iframe2.get(), main_doc->GetDocumentFromFrame("1", "0").get());
}
IN_PROC_BROWSER_TEST_F(DOMAutomationTest, Events) {
ASSERT_TRUE(test_server()->Start());
ui_test_utils::NavigateToURL(browser(), GetTestURL("events/test.html"));
DOMElementProxyRef main_doc = ui_test_utils::GetActiveDOMDocument(browser());
// Click link and make sure text changes.
DOMElementProxyRef link = main_doc->FindElement(By::Selectors("a"));
ASSERT_TRUE(link && link->Click());
ASSERT_NO_FATAL_FAILURE(link->EnsureTextMatches("clicked"));
// Click input button and make sure textfield changes.
DOMElementProxyRef button = main_doc->FindElement(By::Selectors("#button"));
DOMElementProxyRef textfield =
main_doc->FindElement(By::Selectors("#textfield"));
ASSERT_TRUE(textfield && button && button->Click());
ASSERT_NO_FATAL_FAILURE(textfield->EnsureTextMatches("clicked"));
// Type in the textfield.
ASSERT_TRUE(textfield->SetText("test"));
ASSERT_NO_FATAL_FAILURE(textfield->EnsureTextMatches("test"));
// Type in the textarea.
DOMElementProxyRef textarea =
main_doc->FindElement(By::Selectors("textarea"));
ASSERT_TRUE(textarea && textarea->Type("test"));
ASSERT_NO_FATAL_FAILURE(textarea->EnsureTextMatches("textareatest"));
}
IN_PROC_BROWSER_TEST_F(DOMAutomationTest, StringEscape) {
ASSERT_TRUE(test_server()->Start());
ui_test_utils::NavigateToURL(browser(),
GetTestURL("string_escape/test.html"));
DOMElementProxyRef main_doc = ui_test_utils::GetActiveDOMDocument(browser());
DOMElementProxyRef textarea =
main_doc->FindElement(By::Selectors("textarea"));
ASSERT_TRUE(textarea);
ASSERT_NO_FATAL_FAILURE(textarea->EnsureTextMatches(WideToUTF8(L"\u00FF")));
const wchar_t* set_and_expect_strings[] = {
L"\u00FF and \u00FF",
L"\n \t \\",
L"' \""
};
for (size_t i = 0; i < 3; i++) {
ASSERT_TRUE(textarea->SetText(WideToUTF8(set_and_expect_strings[i])));
ASSERT_NO_FATAL_FAILURE(textarea->EnsureTextMatches(
WideToUTF8(set_and_expect_strings[i])));
}
}
} // namespace