blob: c8d7a1fcaa5f1c943533020f28ecbed24151749e [file] [log] [blame]
// 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 "base/task.h"
#include "base/path_service.h"
#include "chrome/browser/dom_ui/dom_ui.h"
#include "chrome/browser/tab_contents/navigation_controller.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/views/html_dialog_view.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/notification_registrar.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "net/test/test_server.h"
namespace {
typedef DOMElementProxy::By By;
class FileBrowseBrowserTest : public InProcessBrowserTest {
public:
FileBrowseBrowserTest() {
EnableDOMAutomation();
}
};
class FileBrowseUiObserver : public NotificationObserver {
public:
FileBrowseUiObserver() : file_browse_tab_(NULL), is_waiting_(false) {
registrar_.Add(this, NotificationType::LOAD_STOP,
NotificationService::AllSources());
registrar_.Add(this, NotificationType::TAB_CONTENTS_DESTROYED,
NotificationService::AllSources());
}
void WaitForFileBrowseLoad() {
if (file_browse_tab_ == NULL) {
is_waiting_ = true;
ui_test_utils::RunMessageLoop();
}
}
// File browse tab deletion is a non-nestable task and BrowserTest would
// not get related notification because test body runs in a task already.
// Uses a periodical check of the dialog window to implement the wait.
void WaitForFileBrowseClose() {
if (file_browse_tab_ != NULL) {
is_waiting_ = true;
ui_test_utils::RunMessageLoop();
}
}
virtual void Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
if (type == NotificationType::LOAD_STOP) {
NavigationController* controller =
Source<NavigationController>(source).ptr();
if (controller) {
TabContents* tab_contents = controller->tab_contents();
if (tab_contents &&
tab_contents->GetURL().SchemeIs(chrome::kChromeUIScheme) &&
tab_contents->GetURL().host() == chrome::kChromeUIFileBrowseHost) {
file_browse_tab_ = tab_contents;
if (is_waiting_) {
is_waiting_ = false;
MessageLoopForUI::current()->Quit();
}
}
}
} else if (type == NotificationType::TAB_CONTENTS_DESTROYED) {
TabContents* tab_contents = Source<TabContents>(source).ptr();
if (file_browse_tab_ == tab_contents) {
file_browse_tab_ = NULL;
if (is_waiting_) {
is_waiting_ = false;
MessageLoopForUI::current()->Quit();
}
}
}
}
TabContents* file_browse_tab() {
return file_browse_tab_;
}
DOMUI* file_browse_ui() {
return file_browse_tab_ ? file_browse_tab_->render_manager()->dom_ui() :
NULL;
}
private:
NotificationRegistrar registrar_;
TabContents* file_browse_tab_;
bool is_waiting_;
DISALLOW_COPY_AND_ASSIGN(FileBrowseUiObserver);
};
IN_PROC_BROWSER_TEST_F(FileBrowseBrowserTest, InputFileTriggerFileBrowse) {
ASSERT_TRUE(test_server()->Start());
ui_test_utils::NavigateToURL(browser(),
test_server()->GetURL("files/input_file.html"));
DOMElementProxyRef doc = ui_test_utils::GetActiveDOMDocument(browser());
DOMElementProxyRef input_file = doc->FindElement(By::Selectors(".single"));
ASSERT_TRUE(input_file);
// Creates FileBrowseUiObserver before we click.
FileBrowseUiObserver observer;
// Click on the input control. This should bring up the FileBrowseUI.
input_file->Click();
observer.WaitForFileBrowseLoad();
DOMUI* file_browser_ui = observer.file_browse_ui();
ASSERT_TRUE(file_browser_ui);
file_browser_ui->CallJavascriptFunction(L"dialogCancelClick");
observer.WaitForFileBrowseClose();
}
} // namespace