summaryrefslogtreecommitdiffstats
path: root/chrome_frame
diff options
context:
space:
mode:
authorkkania@chromium.org <kkania@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-28 21:24:34 +0000
committerkkania@chromium.org <kkania@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-28 21:24:34 +0000
commit50cdc732caacead0d4236716c43342ae14e366f3 (patch)
treebfa49fd0e3ff3a35e16a8201544ed9709136c9df /chrome_frame
parente55a7ddf8a95cd64c620f4536d641fede75d51d0 (diff)
downloadchromium_src-50cdc732caacead0d4236716c43342ae14e366f3.zip
chromium_src-50cdc732caacead0d4236716c43342ae14e366f3.tar.gz
chromium_src-50cdc732caacead0d4236716c43342ae14e366f3.tar.bz2
Add chrome frame tests for common navigation cases to ensure IE still works.
BUG=none TEST=none Review url: http://codereview.chromium.org/2173002 Review URL: http://codereview.chromium.org/2374002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@48527 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame')
-rw-r--r--chrome_frame/chrome_frame.gyp1
-rw-r--r--chrome_frame/test/chrome_frame_test_utils.cc14
-rw-r--r--chrome_frame/test/chrome_frame_test_utils.h13
-rw-r--r--chrome_frame/test/data/no_interference/javascript_redirect.html11
-rw-r--r--chrome_frame/test/data/no_interference/link.html5
-rw-r--r--chrome_frame/test/no_interference_test.cc138
-rw-r--r--chrome_frame/test/simulate_input.cc39
-rw-r--r--chrome_frame/test/simulate_input.h5
-rw-r--r--chrome_frame/test/test_mock_with_web_server.cc48
-rw-r--r--chrome_frame/test/test_mock_with_web_server.h13
10 files changed, 232 insertions, 55 deletions
diff --git a/chrome_frame/chrome_frame.gyp b/chrome_frame/chrome_frame.gyp
index 141a88e..534dcc2 100644
--- a/chrome_frame/chrome_frame.gyp
+++ b/chrome_frame/chrome_frame.gyp
@@ -229,6 +229,7 @@
'test/chrome_frame_automation_mock.h',
'test/http_server.cc',
'test/http_server.h',
+ 'test/no_interference_test.cc',
'test/proxy_factory_mock.cc',
'test/proxy_factory_mock.h',
'test/run_all_unittests.cc',
diff --git a/chrome_frame/test/chrome_frame_test_utils.cc b/chrome_frame/test/chrome_frame_test_utils.cc
index 5ae558b..62be84e 100644
--- a/chrome_frame/test/chrome_frame_test_utils.cc
+++ b/chrome_frame/test/chrome_frame_test_utils.cc
@@ -891,4 +891,18 @@ FilePath GetProfilePathForIE() {
return profile_path;
}
+void DelaySendExtendedKeysEnter(TimedMsgLoop* loop, int delay, char c,
+ int repeat, simulate_input::Modifier mod) {
+ const unsigned int kInterval = 25;
+ unsigned int next_delay = delay;
+ for (int i = 0; i < repeat; i++) {
+ loop->PostDelayedTask(FROM_HERE, NewRunnableFunction(
+ simulate_input::SendExtendedKey, c, mod), next_delay);
+ next_delay += kInterval;
+ }
+
+ loop->PostDelayedTask(FROM_HERE, NewRunnableFunction(
+ simulate_input::SendCharA, VK_RETURN, simulate_input::NONE), next_delay);
+}
+
} // namespace chrome_frame_test
diff --git a/chrome_frame/test/chrome_frame_test_utils.h b/chrome_frame/test/chrome_frame_test_utils.h
index 022b057..b162214 100644
--- a/chrome_frame/test/chrome_frame_test_utils.h
+++ b/chrome_frame/test/chrome_frame_test_utils.h
@@ -25,6 +25,7 @@
#include "chrome_frame/test/simulate_input.h"
#include "chrome_frame/test/window_watchdog.h"
#include "chrome_frame/utils.h"
+#include "gmock/gmock.h"
// Include without path to make GYP build see it.
#include "chrome_tab.h" // NOLINT
@@ -345,6 +346,18 @@ std::wstring GetExeVersion(const std::wstring& exe_path);
// Returns the version of Internet Explorer on the machine.
IEVersion GetInstalledIEVersion();
+// Posts a delayed task to send an extended keystroke |repeat| times with an
+// optional modifier via SendInput. Following this, the enter key is sent.
+void DelaySendExtendedKeysEnter(TimedMsgLoop* loop, int delay, char c,
+ int repeat, simulate_input::Modifier mod);
+
+// Returns an action which posts a delayed task that sends the given
+// scan code via SendInput.
+ACTION_P4(DelaySendScanCode, loop, delay, c, mod) {
+ loop->PostDelayedTask(FROM_HERE, NewRunnableFunction(
+ simulate_input::SendScanCode, c, mod), delay);
+}
+
// A convenience class to close all open IE windows at the end
// of a scope. It's more convenient to do it this way than to
// explicitly call chrome_frame_test::CloseAllIEWindows at the
diff --git a/chrome_frame/test/data/no_interference/javascript_redirect.html b/chrome_frame/test/data/no_interference/javascript_redirect.html
new file mode 100644
index 0000000..5e29ab1
--- /dev/null
+++ b/chrome_frame/test/data/no_interference/javascript_redirect.html
@@ -0,0 +1,11 @@
+<html>
+ <head>
+ <script type="text/javascript">
+ window.onload = function() {
+ var url = "" + window.location;
+ window.location = url.substring(0, url.lastIndexOf("/") + 1) +
+ "empty.html";
+ }
+ </script>
+ </head>
+</html> \ No newline at end of file
diff --git a/chrome_frame/test/data/no_interference/link.html b/chrome_frame/test/data/no_interference/link.html
new file mode 100644
index 0000000..d84da5b
--- /dev/null
+++ b/chrome_frame/test/data/no_interference/link.html
@@ -0,0 +1,5 @@
+<html>
+ <body>
+ <a href="empty.html">Empty page</a>
+ </body>
+</html> \ No newline at end of file
diff --git a/chrome_frame/test/no_interference_test.cc b/chrome_frame/test/no_interference_test.cc
index acd1d5c..f560adb 100644
--- a/chrome_frame/test/no_interference_test.cc
+++ b/chrome_frame/test/no_interference_test.cc
@@ -64,8 +64,6 @@ class NoInterferenceTest : public ChromeFrameTestWithWebServer {
// Launches IE and navigates to |url|, then waits until receiving a quit
// message or the timeout is exceeded.
void LaunchIEAndNavigate(const std::wstring& url) {
- CloseIeAtEndOfScope last_resort_close_ie;
-
EXPECT_CALL(mock_, OnQuit())
.Times(testing::AtMost(1))
.WillOnce(QUIT_LOOP(loop_));
@@ -76,6 +74,7 @@ class NoInterferenceTest : public ChromeFrameTestWithWebServer {
ASSERT_TRUE(mock_.web_browser2() != NULL);
loop_.RunFor(kChromeFrameLongNavigationTimeoutInSeconds);
+ mock_.Uninitialize();
}
const std::wstring GetTestUrl(const wchar_t* relative_path) {
@@ -84,46 +83,153 @@ class NoInterferenceTest : public ChromeFrameTestWithWebServer {
return UTF8ToWide(server_.Resolve(path.c_str()).spec());
}
+ const std::wstring empty_page_url() {
+ return GetTestUrl(L"empty.html");
+ }
+
+ // Returns the url for a page with a single link, which points to the
+ // empty page.
+ const std::wstring link_page_url() {
+ return GetTestUrl(L"link.html");
+ }
+
+ CloseIeAtEndOfScope last_resort_close_ie;
chrome_frame_test::TimedMsgLoop loop_;
- ComStackObjectWithUninitialize<
- testing::StrictMock<MockWebBrowserEventSink> > mock_;
+ CComObjectStackEx<testing::StrictMock<MockWebBrowserEventSink> > mock_;
};
ACTION_P(ExpectIERendererWindowHasFocus, mock) {
mock->ExpectIERendererWindowHasFocus();
}
-// This tests that a new IE renderer window has focus.
-TEST_F(NoInterferenceTest, SimpleFocus) {
- const std::wstring kEmptyFileUrl = GetTestUrl(L"empty.html");
- mock_.ExpectNavigationAndSwitch(kEmptyFileUrl);
+ACTION_P6(DelaySendMouseClickToIE, mock, loop, delay, x, y, button) {
+ loop->PostDelayedTask(FROM_HERE, NewRunnableMethod(mock,
+ &MockWebBrowserEventSink::SendMouseClickToIE, x, y, button), delay);
+}
+
+ACTION_P2(OpenContextMenu, loop, delay) {
+ loop->PostDelayedTask(FROM_HERE, NewRunnableFunction(
+ simulate_input::SendScanCode, VK_F10, simulate_input::SHIFT), delay);
+}
+
+ACTION_P3(SelectItem, loop, delay, index) {
+ chrome_frame_test::DelaySendExtendedKeysEnter(loop, delay, VK_DOWN, index + 1,
+ simulate_input::NONE);
+}
- EXPECT_CALL(mock_, OnIELoad(testing::StrCaseEq(kEmptyFileUrl)))
+// A new IE renderer window should have focus.
+TEST_F(NoInterferenceTest, SimpleFocus) {
+ mock_.ExpectNavigationInIE(empty_page_url());
+ EXPECT_CALL(mock_, OnIELoad(testing::StrCaseEq(empty_page_url())))
.WillOnce(testing::DoAll(
ExpectIERendererWindowHasFocus(&mock_),
VerifyAddressBarUrl(&mock_),
CloseBrowserMock(&mock_)));
- LaunchIEAndNavigate(kEmptyFileUrl);
+ LaunchIEAndNavigate(empty_page_url());
}
-// This tests that window.open does not get intercepted by Chrome Frame.
+// Javascript window.open should open a new window with an IE renderer.
TEST_F(NoInterferenceTest, FLAKY_JavascriptWindowOpen) {
- const std::wstring kEmptyFileUrl = GetTestUrl(L"empty.html");
const std::wstring kWindowOpenUrl = GetTestUrl(L"window_open.html");
ComStackObjectWithUninitialize<
testing::StrictMock<MockWebBrowserEventSink> > new_window_mock;
- mock_.ExpectNavigationAndSwitch(kWindowOpenUrl);
+ mock_.ExpectNavigationInIE(kWindowOpenUrl);
EXPECT_CALL(mock_, OnIELoad(testing::StrCaseEq(kWindowOpenUrl)));
- mock_.ExpectNewWindow(&new_window_mock);
- EXPECT_CALL(new_window_mock, OnIELoad(testing::StrCaseEq(kEmptyFileUrl)))
- .WillOnce(CloseBrowserMock(&new_window_mock));
+ mock_.ExpectNewWindowWithIE(empty_page_url(), &new_window_mock);
+ EXPECT_CALL(new_window_mock, OnIELoad(testing::StrCaseEq(empty_page_url())))
+ .WillOnce(testing::DoAll(
+ VerifyAddressBarUrl(&new_window_mock),
+ CloseBrowserMock(&new_window_mock)));
EXPECT_CALL(new_window_mock, OnQuit())
.WillOnce(CloseBrowserMock(&mock_));
LaunchIEAndNavigate(kWindowOpenUrl);
}
+// Redirecting with window.location in Javascript should work.
+TEST_F(NoInterferenceTest, JavascriptRedirect) {
+ const std::wstring kRedirectUrl = GetTestUrl(L"javascript_redirect.html");
+ mock_.ExpectNavigationInIE(kRedirectUrl);
+ EXPECT_CALL(mock_, OnIELoad(testing::StrCaseEq(kRedirectUrl)))
+ .WillOnce(VerifyAddressBarUrl(&mock_));
+
+ mock_.ExpectNavigationInIE(empty_page_url());
+ EXPECT_CALL(mock_, OnIELoad(testing::StrCaseEq(empty_page_url())))
+ .WillOnce(testing::DoAll(
+ VerifyAddressBarUrl(&mock_),
+ CloseBrowserMock(&mock_)));
+
+ LaunchIEAndNavigate(kRedirectUrl);
+}
+
+TEST_F(NoInterferenceTest, FLAKY_FollowLink) {
+ mock_.ExpectNavigationInIE(link_page_url());
+ EXPECT_CALL(mock_, OnIELoad(testing::StrCaseEq(link_page_url())))
+ .WillOnce(testing::DoAll(
+ DelaySendMouseClickToIE(&mock_, &loop_, 0, 1, 1,
+ simulate_input::LEFT),
+ DelaySendScanCode(&loop_, 500, VK_TAB, simulate_input::NONE),
+ DelaySendScanCode(&loop_, 1000, VK_RETURN, simulate_input::NONE)));
+
+ mock_.ExpectNavigationInIE(empty_page_url());
+ EXPECT_CALL(mock_, OnIELoad(testing::StrCaseEq(empty_page_url())))
+ .WillOnce(testing::DoAll(
+ VerifyAddressBarUrl(&mock_),
+ CloseBrowserMock(&mock_)));
+
+ LaunchIEAndNavigate(link_page_url());
+}
+
+TEST_F(NoInterferenceTest, FLAKY_SelectContextMenuOpen) {
+ mock_.ExpectNavigationInIE(link_page_url());
+ // Focus the renderer window by clicking and then tab once to highlight the
+ // link.
+ EXPECT_CALL(mock_, OnIELoad(testing::StrCaseEq(link_page_url())))
+ .WillOnce(testing::DoAll(
+ DelaySendMouseClickToIE(&mock_, &loop_, 0, 1, 1,
+ simulate_input::LEFT),
+ DelaySendScanCode(&loop_, 500, VK_TAB, simulate_input::NONE),
+ OpenContextMenu(&loop_, 1000),
+ SelectItem(&loop_, 1500, 0)));
+
+ mock_.ExpectNavigationInIE(empty_page_url());
+ EXPECT_CALL(mock_, OnIELoad(testing::StrCaseEq(empty_page_url())))
+ .WillOnce(testing::DoAll(
+ VerifyAddressBarUrl(&mock_),
+ CloseBrowserMock(&mock_)));
+
+ LaunchIEAndNavigate(link_page_url());
+}
+
+TEST_F(NoInterferenceTest, FLAKY_SelectContextMenuOpenInNewWindow) {
+ ComStackObjectWithUninitialize<
+ testing::StrictMock<MockWebBrowserEventSink> > new_window_mock;
+ int open_new_window_index = 2;
+ if (chrome_frame_test::GetInstalledIEVersion() == IE_6)
+ open_new_window_index = 1;
+
+ // Focus the renderer window by clicking and then tab once to highlight the
+ // link.
+ mock_.ExpectNavigationInIE(link_page_url());
+ EXPECT_CALL(mock_, OnIELoad(testing::StrCaseEq(link_page_url())))
+ .WillOnce(testing::DoAll(
+ DelaySendMouseClickToIE(&mock_, &loop_, 0, 1, 1,
+ simulate_input::LEFT),
+ DelaySendScanCode(&loop_, 500, VK_TAB, simulate_input::NONE),
+ OpenContextMenu(&loop_, 1000),
+ SelectItem(&loop_, 1500, open_new_window_index)));
+
+ mock_.ExpectNewWindowWithIE(empty_page_url(), &new_window_mock);
+ // TODO(kkania): Verifying the address bar is flaky with this, at least
+ // on XP ie6. Fix.
+ EXPECT_CALL(new_window_mock, OnIELoad(testing::StrCaseEq(empty_page_url())))
+ .WillOnce(CloseBrowserMock(&new_window_mock));
+ EXPECT_CALL(new_window_mock, OnQuit()).WillOnce(CloseBrowserMock(&mock_));
+
+ LaunchIEAndNavigate(link_page_url());
+}
+
} // namespace \ No newline at end of file
diff --git a/chrome_frame/test/simulate_input.cc b/chrome_frame/test/simulate_input.cc
index 411f72e..68d8edc 100644
--- a/chrome_frame/test/simulate_input.cc
+++ b/chrome_frame/test/simulate_input.cc
@@ -192,29 +192,14 @@ void SetKeyboardFocusToWindow(HWND window) {
SendMouseClick(window, 1, 1, LEFT);
}
-void SendMouseClick(HWND window, int x, int y, MouseButton button) {
- if (!IsWindow(window)) {
- NOTREACHED() << "Invalid window handle.";
- return;
- }
-
- HWND top_level_window = window;
- if (!IsTopLevelWindow(top_level_window)) {
- top_level_window = GetAncestor(window, GA_ROOT);
- }
-
- ForceSetForegroundWindow(top_level_window);
-
- POINT cursor_position = {x, y};
- ClientToScreen(window, &cursor_position);
-
+void SendMouseClick(int x, int y, MouseButton button) {
// TODO(joshia): Fix this. GetSystemMetrics(SM_CXSCREEN) will
// retrieve screen size of the primarary monitor only. And monitors
// arrangement could be pretty arbitrary.
double screen_width = ::GetSystemMetrics(SM_CXSCREEN) - 1;
double screen_height = ::GetSystemMetrics(SM_CYSCREEN) - 1;
- double location_x = cursor_position.x * (65535.0f / screen_width);
- double location_y = cursor_position.y * (65535.0f / screen_height);
+ double location_x = x * (65535.0f / screen_width);
+ double location_y = y * (65535.0f / screen_height);
// Take advantage of button flag bitmask layout
unsigned int button_flag = MOUSEEVENTF_LEFTDOWN << (button + button);
@@ -237,6 +222,24 @@ void SendMouseClick(HWND window, int x, int y, MouseButton button) {
::SendInput(1, &input_info, sizeof(INPUT));
}
+void SendMouseClick(HWND window, int x, int y, MouseButton button) {
+ if (!IsWindow(window)) {
+ NOTREACHED() << "Invalid window handle.";
+ return;
+ }
+
+ HWND top_level_window = window;
+ if (!IsTopLevelWindow(top_level_window)) {
+ top_level_window = GetAncestor(window, GA_ROOT);
+ }
+
+ ForceSetForegroundWindow(top_level_window);
+
+ POINT cursor_position = {x, y};
+ ClientToScreen(window, &cursor_position);
+ SendMouseClick(cursor_position.x, cursor_position.y, button);
+}
+
void SendExtendedKey(WORD key, Modifier modifiers) {
SendMnemonic(key, modifiers, true, false);
}
diff --git a/chrome_frame/test/simulate_input.h b/chrome_frame/test/simulate_input.h
index 135c310..fab22a8 100644
--- a/chrome_frame/test/simulate_input.h
+++ b/chrome_frame/test/simulate_input.h
@@ -37,8 +37,11 @@ void SetKeyboardFocusToWindow(HWND window);
void SendMnemonic(WORD mnemonic_char, Modifier modifiers, bool extended,
bool unicode);
-// Sends a mouse click to the window passed in.
+// Sends a mouse click to the desktop.
enum MouseButton { LEFT, RIGHT, MIDDLE, X };
+void SendMouseClick(int x, int y, MouseButton button);
+// Sends a mouse click to the window passed in, after ensuring that the window
+// is in the foreground.
void SendMouseClick(HWND window, int x, int y, MouseButton button);
// Translates a single char to a virtual key.
diff --git a/chrome_frame/test/test_mock_with_web_server.cc b/chrome_frame/test/test_mock_with_web_server.cc
index f869bb7..174311d 100644
--- a/chrome_frame/test/test_mock_with_web_server.cc
+++ b/chrome_frame/test/test_mock_with_web_server.cc
@@ -147,6 +147,34 @@ ExpectationSet MockWebBrowserEventSink::ExpectNewWindow(
return new_window;
}
+ExpectationSet MockWebBrowserEventSink::ExpectNavigationInIE(
+ const std::wstring& url) {
+ testing::InSequence sequence;
+ ExpectationSet navigation;
+ navigation += EXPECT_CALL(*this, OnBeforeNavigate2(_,
+ testing::Field(&VARIANT::bstrVal,
+ testing::StrCaseEq(url)), _, _, _, _, _));
+ navigation += EXPECT_CALL(*this, OnFileDownload(VARIANT_TRUE, _))
+ .Times(testing::AnyNumber());
+ navigation += EXPECT_CALL(*this, OnNavigateComplete2(_,
+ testing::Field(&VARIANT::bstrVal,
+ testing::StrCaseEq(url))));
+ return navigation;
+}
+
+ExpectationSet MockWebBrowserEventSink::ExpectNewWindowWithIE(
+ const std::wstring& url, MockWebBrowserEventSink* new_window_mock) {
+ DCHECK(new_window_mock);
+ ExpectationSet new_window;
+ new_window += EXPECT_CALL(*this, OnNewWindow3(_, _, _, _, _));
+ new_window += EXPECT_CALL(*this, OnNewBrowserWindow(_, _))
+ .WillOnce(testing::WithArgs<0>(testing::Invoke(CreateFunctor(
+ new_window_mock, &MockWebBrowserEventSink::Attach))));
+
+ new_window_mock->ExpectNavigationInIE(url);
+ return new_window;
+}
+
} // namespace chrome_frame_test
ACTION_P3(DelayCloseBrowserMock, loop, delay, mock) {
@@ -180,27 +208,13 @@ ACTION_P4(DelaySendChar, loop, delay, c, mod) {
simulate_input::SendCharA, c, mod), delay);
}
-ACTION_P4(DelaySendScanCode, loop, delay, c, mod) {
+ACTION_P3(DelaySendString, loop, delay, str) {
loop->PostDelayedTask(FROM_HERE, NewRunnableFunction(
- simulate_input::SendScanCode, c, mod), delay);
+ simulate_input::SendStringW, str), delay);
}
ACTION_P5(SendExtendedKeysEnter, loop, delay, c, repeat, mod) {
- const unsigned int kInterval = 25;
- unsigned int next_delay = delay;
- for (int i = 0; i < repeat; i++) {
- loop->PostDelayedTask(FROM_HERE, NewRunnableFunction(
- simulate_input::SendExtendedKey, c, mod), next_delay);
- next_delay += kInterval;
- }
-
- loop->PostDelayedTask(FROM_HERE, NewRunnableFunction(
- simulate_input::SendCharA, VK_RETURN, simulate_input::NONE), next_delay);
-}
-
-ACTION_P3(DelaySendString, loop, delay, str) {
- loop->PostDelayedTask(FROM_HERE, NewRunnableFunction(
- simulate_input::SendStringW, str), delay);
+ chrome_frame_test::DelaySendExtendedKeysEnter(loop, delay, c, repeat, mod);
}
ACTION(DoCloseWindow) {
diff --git a/chrome_frame/test/test_mock_with_web_server.h b/chrome_frame/test/test_mock_with_web_server.h
index 53fccb1..2d71721 100644
--- a/chrome_frame/test/test_mock_with_web_server.h
+++ b/chrome_frame/test/test_mock_with_web_server.h
@@ -75,15 +75,22 @@ class MockWebBrowserEventSink : public chrome_frame_test::WebBrowserEventSink {
MOCK_METHOD2(OnWindowDetected, void (HWND hwnd, // NOLINT
const std::string& caption));
- // Test expectations
+ // Test expectations for general navigations.
ExpectationSet ExpectNavigationCardinality(const std::wstring& url,
testing::Cardinality cardinality);
ExpectationSet ExpectNavigation(const std::wstring& url);
ExpectationSet ExpectNavigationAndSwitch(const std::wstring& url);
ExpectationSet ExpectNavigationAndSwitchSequence(const std::wstring& url);
ExpectationSet ExpectNewWindow(MockWebBrowserEventSink* new_window_mock);
- ExpectationSet MockWebBrowserEventSink::ExpectNavigationSequenceForAnchors(
- const std::wstring& url);
+ ExpectationSet ExpectNavigationSequenceForAnchors(const std::wstring& url);
+
+ // Test expectations for navigations with an IE renderer.
+ // Expect one navigation to occur.
+ ExpectationSet ExpectNavigationInIE(const std::wstring& url);
+ // Expect a new window to be opened to |url|. Set |new_window_mock| as the new
+ // window.
+ ExpectationSet ExpectNewWindowWithIE(
+ const std::wstring& url, MockWebBrowserEventSink* new_window_mock);
};
ACTION_P(CloseBrowserMock, mock) {