summaryrefslogtreecommitdiffstats
path: root/chrome_frame
diff options
context:
space:
mode:
authoramit@chromium.org <amit@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-23 23:08:18 +0000
committeramit@chromium.org <amit@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-23 23:08:18 +0000
commit2cc1b3b02becea91928f24aecbf30b54c6b30329 (patch)
tree84068c23ff3e3bc11ffc0f0e834c4a8b8dbd9921 /chrome_frame
parent8048a15e53387dd181a9b0dd4548b042320e01d0 (diff)
downloadchromium_src-2cc1b3b02becea91928f24aecbf30b54c6b30329.zip
chromium_src-2cc1b3b02becea91928f24aecbf30b54c6b30329.tar.gz
chromium_src-2cc1b3b02becea91928f24aecbf30b54c6b30329.tar.bz2
Unit test for back/forward for url fragments. Improvements in the testing
framwork include a non-scriptable interface for getting window handles from chrome frame activex and methods for sending input in the WebBrowserSink. BUG=none TEST=back forward unit test for url fragments (anchor) Review URL: http://codereview.chromium.org/430002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@32882 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame')
-rw-r--r--chrome_frame/test/chrome_frame_test_utils.cc6
-rw-r--r--chrome_frame/test/chrome_frame_unittests.cc218
-rw-r--r--chrome_frame/test/chrome_frame_unittests.h21
3 files changed, 227 insertions, 18 deletions
diff --git a/chrome_frame/test/chrome_frame_test_utils.cc b/chrome_frame/test/chrome_frame_test_utils.cc
index 2cce441..8777651 100644
--- a/chrome_frame/test/chrome_frame_test_utils.cc
+++ b/chrome_frame/test/chrome_frame_test_utils.cc
@@ -472,7 +472,7 @@ void SetKeyboardFocusToWindow(HWND window, int x, int y) {
}
void SendInputToWindow(HWND window, const std::string& input_string) {
- SetKeyboardFocusToWindow(window, 100, 100);
+ const unsigned long kIntervalBetweenInput = 100;
for (size_t index = 0; index < input_string.length(); index++) {
bool is_upper_case = isupper(input_string[index]);
@@ -481,18 +481,20 @@ void SendInputToWindow(HWND window, const std::string& input_string) {
input.ki.wVk = VK_SHIFT;
input.ki.dwFlags = 0;
SendInput(1, &input, sizeof(input));
- Sleep(200);
+ Sleep(kIntervalBetweenInput);
}
// The WM_KEYDOWN and WM_KEYUP messages for characters always contain
// the uppercase character codes.
SendVirtualKey(toupper(input_string[index]), false);
+ Sleep(kIntervalBetweenInput);
if (is_upper_case) {
INPUT input = { INPUT_KEYBOARD };
input.ki.wVk = VK_SHIFT;
input.ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(1, &input, sizeof(input));
+ Sleep(kIntervalBetweenInput);
}
}
}
diff --git a/chrome_frame/test/chrome_frame_unittests.cc b/chrome_frame/test/chrome_frame_unittests.cc
index 92ba2d0..cf7e6a0 100644
--- a/chrome_frame/test/chrome_frame_unittests.cc
+++ b/chrome_frame/test/chrome_frame_unittests.cc
@@ -848,6 +848,11 @@ struct TimedMsgLoop {
loop_.MessageLoop::Run();
}
+ void PostDelayedTask(
+ const tracked_objects::Location& from_here, Task* task, int64 delay_ms) {
+ loop_.PostDelayedTask(from_here, task, delay_ms);
+ }
+
void Quit() {
loop_.PostTask(FROM_HERE, new MessageLoop::QuitTask);
}
@@ -1221,6 +1226,15 @@ HRESULT LaunchIEAsComServer(IWebBrowser2** web_browser) {
}
// WebBrowserEventSink member defines
+void WebBrowserEventSink::Uninitialize() {
+ chrome_frame_ = NULL;
+ if (web_browser2_.get()) {
+ DispEventUnadvise(web_browser2_);
+ web_browser2_->Quit();
+ web_browser2_.Release();
+ }
+}
+
STDMETHODIMP WebBrowserEventSink::OnBeforeNavigate2Internal(
IDispatch* dispatch, VARIANT* url, VARIANT* flags,
VARIANT* target_frame_name, VARIANT* post_data, VARIANT* headers,
@@ -1282,6 +1296,15 @@ HRESULT WebBrowserEventSink::Navigate(const std::wstring& navigate_url) {
return hr;
}
+void WebBrowserEventSink::SetFocusToChrome() {
+ chrome_frame_test::SetKeyboardFocusToWindow(GetChromeRendererWindow(), 1, 1);
+}
+
+void WebBrowserEventSink::SendInputToChrome(
+ const std::string& input_string) {
+ chrome_frame_test::SendInputToWindow(GetChromeRendererWindow(), input_string);
+}
+
void WebBrowserEventSink::ConnectToChromeFrame() {
DCHECK(web_browser2_);
ScopedComPtr<IShellBrowser> shell_browser;
@@ -1307,6 +1330,28 @@ void WebBrowserEventSink::ConnectToChromeFrame() {
}
}
+HWND WebBrowserEventSink::GetChromeRendererWindow() {
+ DCHECK(chrome_frame_);
+ HWND renderer_window = NULL;
+ ScopedComPtr<IOleWindow> ole_window;
+ ole_window.QueryFrom(chrome_frame_);
+ EXPECT_TRUE(ole_window.get());
+
+ if (ole_window) {
+ HWND activex_window = NULL;
+ ole_window->GetWindow(&activex_window);
+ EXPECT_TRUE(IsWindow(activex_window));
+
+ // chrome tab window is the first (and the only) child of activex
+ HWND chrome_tab_window = GetWindow(activex_window, GW_CHILD);
+ EXPECT_TRUE(IsWindow(chrome_tab_window));
+ renderer_window = GetWindow(chrome_tab_window, GW_CHILD);
+ }
+
+ DCHECK(IsWindow(renderer_window));
+ return renderer_window;
+}
+
const int kChromeFrameLaunchDelay = 5;
const int kChromeFrameLongNavigationTimeoutInSeconds = 10;
@@ -1508,6 +1553,7 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_ChromeFrameKeyboardTest) {
HWND renderer_window = chrome_frame_test::GetChromeRendererWindow();
EXPECT_TRUE(IsWindow(renderer_window));
+ chrome_frame_test::SetKeyboardFocusToWindow(renderer_window, 1, 1);
chrome_frame_test::SendInputToWindow(renderer_window, "Chrome");
loop.RunFor(kChromeFrameLongNavigationTimeoutInSeconds);
@@ -1600,7 +1646,12 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_BackForward) {
EXPECT_CALL(mock, OnNavigateComplete2(_, _))
.WillOnce(testing::Return());
EXPECT_CALL(mock, OnLoad(testing::StrEq(kSubFrameUrl1)))
- .WillOnce(QUIT_LOOP_SOON(loop, 2));
+ .WillOnce(testing::DoAll(
+ testing::InvokeWithoutArgs(CreateFunctor(&mock,
+ &WebBrowserEventSink::Uninitialize)),
+ testing::IgnoreResult(testing::InvokeWithoutArgs(
+ &chrome_frame_test::CloseAllIEWindows)),
+ QUIT_LOOP_SOON(loop, 2)));
HRESULT hr = mock.LaunchIEAndNavigate(kSubFrameUrl1);
ASSERT_HRESULT_SUCCEEDED(hr);
@@ -1608,13 +1659,10 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_BackForward) {
return;
ASSERT_TRUE(mock.web_browser2() != NULL);
-
loop.RunFor(kChromeFrameLongNavigationTimeoutInSeconds);
-
- mock.Uninitialize();
- chrome_frame_test::CloseAllIEWindows();
}
+
const wchar_t kChromeFrameAboutBlankUrl[] = L"cf:about:blank";
TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_ChromeFrameFocusTest) {
@@ -1641,3 +1689,163 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_ChromeFrameFocusTest) {
chrome_frame_test::CloseAllIEWindows();
}
+const wchar_t kAnchorUrl[] = L"http://localhost:1337/files/anchor.html";
+const wchar_t kAnchor1Url[] = L"http://localhost:1337/files/anchor.html#a1";
+const wchar_t kAnchor2Url[] = L"http://localhost:1337/files/anchor.html#a2";
+const wchar_t kAnchor3Url[] = L"http://localhost:1337/files/anchor.html#a3";
+
+// Full tab mode back/forward test
+// Launch and navigate chrome frame to a set of URLs and test back forward
+TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_BackForwardAnchor) {
+ const char tab_enter_keystrokes[] = { VK_TAB, VK_RETURN, 0 };
+ static const std::string tab_enter(tab_enter_keystrokes);
+ TimedMsgLoop loop;
+ CComObjectStackEx<MockWebBrowserEventSink> mock;
+ ::testing::InSequence sequence; // Everything in sequence
+
+ // Back/Forward state at this point:
+ // Back: 0
+ // Forward: 0
+ EXPECT_CALL(mock, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal,
+ testing::StrCaseEq(kAnchorUrl)),
+ _, _, _, _, _))
+ .WillOnce(testing::Return(S_OK));
+ EXPECT_CALL(mock, OnNavigateComplete2(_, _))
+ .WillOnce(testing::Return());
+
+ // Navigate to anchor 1:
+ // - First set focus to chrome renderer window
+ // Call WebBrowserEventSink::SetFocusToChrome only once
+ // in the beginning. Calling it again will change focus from the
+ // current location to an element near the simulated mouse.click.
+ // - Then send keyboard input of TAB + ENTER to cause navigation.
+ // It's better to send input as PostDelayedTask since the Activex
+ // message loop on the other side might be blocked when we get
+ // called in Onload.
+ EXPECT_CALL(mock, OnLoad(testing::StrEq(kAnchorUrl)))
+ .WillOnce(testing::DoAll(
+ testing::InvokeWithoutArgs(CreateFunctor(&mock,
+ &WebBrowserEventSink::SetFocusToChrome)),
+ testing::InvokeWithoutArgs(CreateFunctor(&loop,
+ &TimedMsgLoop::PostDelayedTask, FROM_HERE, NewRunnableMethod(
+ &mock, &WebBrowserEventSink::SendInputToChrome,
+ std::string(tab_enter)), 0))));
+ EXPECT_CALL(mock, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal,
+ testing::StrCaseEq(kAnchor1Url)),
+ _, _, _, _, _))
+ .WillOnce(testing::Return(S_OK));
+ EXPECT_CALL(mock, OnNavigateComplete2(_, _))
+ .WillOnce(testing::Return());
+
+ // Navigate to anchor 2 after the previous navigation is complete
+ // Back/Forward state at this point:
+ // Back: 1 (kAnchorUrl)
+ // Forward: 0
+ EXPECT_CALL(mock, OnLoad(testing::StrEq(kAnchor1Url)))
+ .WillOnce(testing::InvokeWithoutArgs(
+ CreateFunctor(&loop, &TimedMsgLoop::PostDelayedTask, FROM_HERE,
+ NewRunnableMethod(&mock, &WebBrowserEventSink::SendInputToChrome,
+ std::string(tab_enter)), 0)));
+ EXPECT_CALL(mock, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal,
+ testing::StrCaseEq(kAnchor2Url)),
+ _, _, _, _, _))
+ .WillOnce(testing::Return(S_OK));
+ EXPECT_CALL(mock, OnNavigateComplete2(_, _))
+ .WillOnce(testing::Return());
+
+ // Navigate to anchor 3 after the previous navigation is complete
+ // Back/Forward state at this point:
+ // Back: 2 (kAnchorUrl, kAnchor1Url)
+ // Forward: 0
+ EXPECT_CALL(mock, OnLoad(testing::StrEq(kAnchor2Url)))
+ .WillOnce(testing::InvokeWithoutArgs(
+ CreateFunctor(&loop, &TimedMsgLoop::PostDelayedTask, FROM_HERE,
+ NewRunnableMethod(&mock, &WebBrowserEventSink::SendInputToChrome,
+ std::string(tab_enter)), 0)));
+ EXPECT_CALL(mock, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal,
+ testing::StrCaseEq(kAnchor3Url)),
+ _, _, _, _, _))
+ .WillOnce(testing::Return(S_OK));
+ EXPECT_CALL(mock, OnNavigateComplete2(_, _))
+ .WillOnce(testing::Return());
+
+ // We will reach anchor 3 once the navigation is complete,
+ // then go back to anchor 2
+ // Back/Forward state at this point:
+ // Back: 3 (kAnchorUrl, kAnchor1Url, kAnchor2Url)
+ // Forward: 0
+ EXPECT_CALL(mock, OnLoad(testing::StrEq(kAnchor3Url)))
+ .WillOnce(testing::IgnoreResult(testing::InvokeWithoutArgs(
+ CreateFunctor(ReceivePointer(mock.web_browser2_),
+ &IWebBrowser::GoBack))));
+ EXPECT_CALL(mock, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal,
+ testing::StrCaseEq(kAnchor2Url)),
+ _, _, _, _, _))
+ .WillOnce(testing::Return(S_OK));
+ EXPECT_CALL(mock, OnNavigateComplete2(_, _))
+ .WillOnce(testing::Return());
+
+ // We will reach anchor 2 once the navigation is complete,
+ // then go back to anchor 1
+ // Back/Forward state at this point:
+ // Back: 3 (kAnchorUrl, kAnchor1Url, kAnchor2Url)
+ // Forward: 1 (kAnchor3Url)
+ EXPECT_CALL(mock, OnLoad(testing::StrEq(kAnchor2Url)))
+ .WillOnce(testing::IgnoreResult(testing::InvokeWithoutArgs(
+ CreateFunctor(ReceivePointer(mock.web_browser2_),
+ &IWebBrowser::GoBack))));
+ EXPECT_CALL(mock, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal,
+ testing::StrCaseEq(kAnchor1Url)),
+ _, _, _, _, _))
+ .WillOnce(testing::Return(S_OK));
+ EXPECT_CALL(mock, OnNavigateComplete2(_, _))
+ .WillOnce(testing::Return());
+
+ // We will reach anchor 1 once the navigation is complete,
+ // now go forward to anchor 2
+ // Back/Forward state at this point:
+ // Back: 2 (kAnchorUrl, kAnchor1Url)
+ // Forward: 2 (kAnchor2Url, kAnchor3Url)
+ EXPECT_CALL(mock, OnLoad(testing::StrEq(kAnchor1Url)))
+ .WillOnce(testing::IgnoreResult(testing::InvokeWithoutArgs(
+ CreateFunctor(ReceivePointer(mock.web_browser2_),
+ &IWebBrowser::GoForward))));
+ EXPECT_CALL(mock, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal,
+ testing::StrCaseEq(kAnchor2Url)),
+ _, _, _, _, _))
+ .WillOnce(testing::Return(S_OK));
+ EXPECT_CALL(mock, OnNavigateComplete2(_, _))
+ .WillOnce(testing::Return());
+
+ // We have reached anchor 2, go forward to anchor 3 again
+ // Back/Forward state at this point:
+ // Back: 3 (kAnchorUrl, kAnchor1Url, kAnchor2Url)
+ // Forward: 1 (kAnchor3Url)
+ EXPECT_CALL(mock, OnLoad(testing::StrEq(kAnchor2Url)))
+ .WillOnce(testing::IgnoreResult(testing::InvokeWithoutArgs(
+ CreateFunctor(ReceivePointer(mock.web_browser2_),
+ &IWebBrowser::GoForward))));
+ EXPECT_CALL(mock, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal,
+ testing::StrCaseEq(kAnchor3Url)),
+ _, _, _, _, _))
+ .WillOnce(testing::Return(S_OK));
+ EXPECT_CALL(mock, OnNavigateComplete2(_, _))
+ .WillOnce(testing::Return());
+
+ // We have gone a few steps back and forward, this should be enough for now.
+ EXPECT_CALL(mock, OnLoad(testing::StrEq(kAnchor3Url)))
+ .WillOnce(testing::DoAll(
+ testing::InvokeWithoutArgs(CreateFunctor(&mock,
+ &WebBrowserEventSink::Uninitialize)),
+ testing::IgnoreResult(testing::InvokeWithoutArgs(
+ &chrome_frame_test::CloseAllIEWindows)),
+ QUIT_LOOP_SOON(loop, 2)));
+
+ HRESULT hr = mock.LaunchIEAndNavigate(kAnchorUrl);
+ ASSERT_HRESULT_SUCCEEDED(hr);
+ if (hr == S_FALSE)
+ return;
+
+ ASSERT_TRUE(mock.web_browser2() != NULL);
+ loop.RunFor(kChromeFrameLongNavigationTimeoutInSeconds);
+}
diff --git a/chrome_frame/test/chrome_frame_unittests.h b/chrome_frame/test/chrome_frame_unittests.h
index 7ecdf50..c39058b 100644
--- a/chrome_frame/test/chrome_frame_unittests.h
+++ b/chrome_frame/test/chrome_frame_unittests.h
@@ -128,16 +128,7 @@ class WebBrowserEventSink
Uninitialize();
}
- void Uninitialize() {
- chrome_frame_ = NULL;
- if (web_browser2_.get()) {
- DispEventUnadvise(web_browser2_);
- web_browser2_->Quit();
- web_browser2_.Release();
- // Give IE some time to quit and release our references
- Sleep(1000);
- }
- }
+ void Uninitialize();
// Helper function to launch IE and navigate to a URL.
// Returns S_OK on success, S_FALSE if the test was not run, other
@@ -146,6 +137,13 @@ class WebBrowserEventSink
HRESULT Navigate(const std::wstring& navigate_url);
+ // Set input focus to chrome frame window.
+ void SetFocusToChrome();
+
+ // Send keyboard input to the renderer window hosted in chrome using
+ // SendInput API
+ void SendInputToChrome(const std::string& input_string);
+
BEGIN_COM_MAP(WebBrowserEventSink)
END_COM_MAP()
@@ -212,7 +210,8 @@ END_SINK_MAP()
HRESULT OnLoadErrorInternal(const VARIANT* param);
HRESULT OnMessageInternal(const VARIANT* param);
- void ConnectToChromeFrame();
+ void ConnectToChromeFrame();
+ HWND GetChromeRendererWindow();
public:
ScopedComPtr<IWebBrowser2> web_browser2_;