Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(511)

Unified Diff: content/browser/frame_host/interstitial_page_impl_browsertest.cc

Issue 1162373002: Make some editing/selection functions accessible to c/b/renderer_host/ (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Switched to oninput event as oncut/onpaste happen before cut/paste Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/frame_host/interstitial_page_impl_browsertest.cc
diff --git a/content/browser/frame_host/interstitial_page_impl_browsertest.cc b/content/browser/frame_host/interstitial_page_impl_browsertest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..df622061669983af9bcdbc79f27cb5ad1db950fd
--- /dev/null
+++ b/content/browser/frame_host/interstitial_page_impl_browsertest.cc
@@ -0,0 +1,268 @@
+// Copyright 2015 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 "content/browser/frame_host/interstitial_page_impl.h"
+
+#include "base/auto_reset.h"
+#include "base/strings/utf_string_conversions.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/common/frame_messages.h"
+#include "content/public/browser/browser_message_filter.h"
+#include "content/public/browser/interstitial_page_delegate.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/test_utils.h"
+#include "content/shell/browser/shell.h"
+#include "ui/base/clipboard/scoped_clipboard_writer.h"
+#include "ui/base/test/test_clipboard.h"
+
+namespace content {
+
+namespace {
+
+class TestInterstitialPageDelegate : public InterstitialPageDelegate {
+ private:
+ // InterstitialPageDelegate:
+ std::string GetHTMLContents() override {
+ return "<html>"
+ "<head>"
+ "<title>LOADED</title>"
+ "<script>"
+ "function focus_select_input() {"
+ " document.getElementById('input').select();"
+ "}"
+ "function set_input_text(text) {"
+ " document.getElementById('input').value = text;"
+ "}"
+ "function get_input_text() {"
+ " return document.getElementById('input').value;"
+ "}"
+ "</script>"
+ "</head>"
+ "<body>"
+ " <input id='input' oninput='document.title=\"TEXT_CHANGED\"'>"
+ "</body>"
+ "</html>";
+ }
+};
+
+class TitleUpdateWatcher : public BrowserMessageFilter {
nasko 2015/06/26 11:35:39 Is the existing TitleWatcher insufficient for this
mohsen 2015/06/26 19:57:56 The existing one does not work for interstitial pa
nasko 2015/06/29 09:30:24 If this is the case, let's name the class to indic
mohsen 2015/06/29 21:46:53 Done.
+ public:
+ TitleUpdateWatcher()
+ : BrowserMessageFilter(FrameMsgStart),
+ waiting_(false),
+ title_updated_(false) {}
+
+ void InitWait(const std::string& expected_title) {
+ expected_title_ = base::ASCIIToUTF16(expected_title);
+ waiting_ = false;
+ title_updated_ = false;
+ }
+
+ void Wait() {
+ DCHECK(!waiting_);
+ if (title_updated_)
+ return;
+ base::RunLoop run_loop;
+ base::AutoReset<base::Closure> reset_quit_closure(&quit_closure_,
+ run_loop.QuitClosure());
+ base::AutoReset<bool> reset_waiting(&waiting_, true);
+ run_loop.Run();
+ }
+
+ private:
+ ~TitleUpdateWatcher() override {}
+
+ void OnTitleUpdateReceived(const base::string16& title) {
+ if (title == expected_title_) {
+ title_updated_ = true;
+ if (waiting_) {
+ waiting_ = false;
+ quit_closure_.Run();
+ }
+ }
+ }
+
+ // BrowserMessageFilter:
+ bool OnMessageReceived(const IPC::Message& message) override {
+ if (message.type() == FrameHostMsg_UpdateTitle::ID) {
+ FrameHostMsg_UpdateTitle::Param params;
+ if (FrameHostMsg_UpdateTitle::Read(&message, &params)) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&TitleUpdateWatcher::OnTitleUpdateReceived, this,
+ base::get<0>(params)));
+ }
+ }
+ return false;
+ }
+
+ base::string16 expected_title_;
+ bool waiting_;
+ bool title_updated_;
+ base::Closure quit_closure_;
+
+ DISALLOW_COPY_AND_ASSIGN(TitleUpdateWatcher);
+};
+
+} // namespace
+
+class InterstitialPageImplTest : public ContentBrowserTest {
+ public:
+ InterstitialPageImplTest()
+ : web_contents_(nullptr),
+ interstitial_delegate_(nullptr),
+ clipboard_(static_cast<ui::TestClipboard*>(
+ ui::TestClipboard::CreateForCurrentThread())),
+ title_update_watcher_(nullptr) {}
+
+ ~InterstitialPageImplTest() override {}
+
+ protected:
+ void FocusInputAndSelectText() {
+ ExecuteScriptAndGetValue(interstitial_->GetMainFrame(),
+ "focus_select_input()");
+ }
+
+ std::string GetInputText() {
+ scoped_ptr<base::Value> input_value = ExecuteScriptAndGetValue(
+ interstitial_->GetMainFrame(), "get_input_text()");
+ std::string input_text;
+ input_value->GetAsString(&input_text);
+ return input_text;
+ }
+
+ void SetInputText(const std::string& text) {
+ ExecuteScriptAndGetValue(interstitial_->GetMainFrame(),
+ "set_input_text('" + text + "')");
+ }
+
+ void PerformCut() {
+ clipboard_->ResetWaits();
+ title_update_watcher_->InitWait("TEXT_CHANGED");
+ RenderFrameHostImpl* rfh =
+ static_cast<RenderFrameHostImpl*>(interstitial_->GetMainFrame());
+ rfh->GetRenderWidgetHost()->delegate()->Cut();
+ clipboard_->WaitForWriteText();
+ title_update_watcher_->Wait();
+ }
+
+ void PerformCopy() {
+ clipboard_->ResetWaits();
nasko 2015/06/26 11:35:38 Why not use the title watcher here as well? Mostly
mohsen 2015/06/26 19:57:56 The title is only updated on events that change va
+ RenderFrameHostImpl* rfh =
+ static_cast<RenderFrameHostImpl*>(interstitial_->GetMainFrame());
+ rfh->GetRenderWidgetHost()->delegate()->Copy();
+ clipboard_->WaitForWriteText();
+ }
+
+ void PerformPaste() {
+ title_update_watcher_->InitWait("TEXT_CHANGED");
+ RenderFrameHostImpl* rfh =
+ static_cast<RenderFrameHostImpl*>(interstitial_->GetMainFrame());
+ rfh->GetRenderWidgetHost()->delegate()->Paste();
+ title_update_watcher_->Wait();
+ }
+
+ void ClearClipboard() {
+ clipboard_->Clear(ui::CLIPBOARD_TYPE_COPY_PASTE);
+ }
+
+ std::string GetClipboardText() {
+ std::string clipboard_text;
+ clipboard_->ReadAsciiText(ui::CLIPBOARD_TYPE_COPY_PASTE,
+ &clipboard_text);
nasko 2015/06/26 11:35:38 nit: This indentation doesn't look right. Should b
mohsen 2015/06/26 19:57:56 Done.
+ return clipboard_text;
+ }
+
+ void SetClipboardText(const std::string& text) {
+ ui::ScopedClipboardWriter clipboard_writer(ui::CLIPBOARD_TYPE_COPY_PASTE);
+ clipboard_writer.WriteText(base::ASCIIToUTF16(text));
+ }
+
+ private:
+ void SetUpOnMainThread() override {
+ ContentBrowserTest::SetUpOnMainThread();
+
+ web_contents_ = static_cast<WebContentsImpl*>(shell()->web_contents());
+
+ // Create the interstitial page.
nasko 2015/06/26 11:35:38 This is a lot of setup that is happening before th
mohsen 2015/06/26 19:57:56 Done.
+ interstitial_delegate_ = new TestInterstitialPageDelegate;
+ GURL url("http://interstitial");
+ interstitial_.reset(new InterstitialPageImpl(
+ web_contents_, static_cast<RenderWidgetHostDelegate*>(web_contents_),
+ true, url, interstitial_delegate_));
+ interstitial_->Show();
+ WaitForInterstitialAttach(web_contents_);
+
+ // Focus the interstitial frame
+ FrameTree* frame_tree = static_cast<RenderViewHostDelegate*>(
+ interstitial_.get())->GetFrameTree();
+ frame_tree->SetFocusedFrame(frame_tree->root());
+
+ title_update_watcher_ = new TitleUpdateWatcher;
+ interstitial_->GetMainFrame()->GetProcess()->AddFilter(
+ title_update_watcher_);
+
+ if (web_contents_->GetTitle() != base::ASCIIToUTF16("LOADED")) {
+ title_update_watcher_->InitWait("LOADED");
+ title_update_watcher_->Wait();
+ }
+ }
+
+ void TearDownOnMainThread() override {
+ // Close the interstitial.
+ interstitial_->DontProceed();
+ WaitForInterstitialDetach(web_contents_);
+ interstitial_.reset();
+ interstitial_delegate_ = nullptr;
+ web_contents_ = nullptr;
+
+ ContentBrowserTest::TearDownOnMainThread();
+ }
+
+ WebContentsImpl* web_contents_;
+ TestInterstitialPageDelegate* interstitial_delegate_;
+ scoped_ptr<InterstitialPageImpl> interstitial_;
+ ui::TestClipboard* const clipboard_;
+ TitleUpdateWatcher* title_update_watcher_;
+
+ DISALLOW_COPY_AND_ASSIGN(InterstitialPageImplTest);
+};
+
+IN_PROC_BROWSER_TEST_F(InterstitialPageImplTest, Cut) {
+ ClearClipboard();
+
+ SetInputText("text-to-cut");
+ FocusInputAndSelectText();
+
+ PerformCut();
+
+ EXPECT_EQ(std::string(), GetInputText());
+ EXPECT_EQ("text-to-cut", GetClipboardText());
+}
+
+IN_PROC_BROWSER_TEST_F(InterstitialPageImplTest, Copy) {
+ ClearClipboard();
+
+ SetInputText("text-to-copy");
+ FocusInputAndSelectText();
+
+ PerformCopy();
+
+ EXPECT_EQ("text-to-copy", GetInputText());
+ EXPECT_EQ("text-to-copy", GetClipboardText());
+}
+
+IN_PROC_BROWSER_TEST_F(InterstitialPageImplTest, Paste) {
+ SetClipboardText("text-to-paste");
+
+ SetInputText("");
+ FocusInputAndSelectText();
+
+ PerformPaste();
+
+ EXPECT_EQ("text-to-paste", GetInputText());
+}
+
+} // namespace content

Powered by Google App Engine
This is Rietveld 408576698