Commit 45671618 authored by jcampan@chromium.org's avatar jcampan@chromium.org

Migrating the SSL UI tests to be browser tests.

Reenabling all of them.
Hopefully it'll help with flakiness.

Note that I am keeping the SSL UI tests alive until the browser test framework has been ported to Mac and Linux.

BUG=6584,2136
TEST=Run the browser tests.
Review URL: http://codereview.chromium.org/101013

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@14901 0039d316-1c4b-4281-b951-d872f2087c98
parent 30369d92
...@@ -264,11 +264,12 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusTraversal) { ...@@ -264,11 +264,12 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusTraversal) {
// Now let's press tab to move the focus. // Now let's press tab to move the focus.
for (int j = 0; j < 7; ++j) { for (int j = 0; j < 7; ++j) {
// Let's make sure the focus is on the expected element in the page. // Let's make sure the focus is on the expected element in the page.
ui_test_utils::JavaScriptRunner js_runner( std::string actual;
ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
browser()->GetSelectedTabContents()->AsWebContents(), browser()->GetSelectedTabContents()->AsWebContents(),
L"", L"",
L"window.domAutomationController.send(getFocusedElement());"); L"window.domAutomationController.send(getFocusedElement());",
std::string actual = js_runner.Run(); &actual));
ASSERT_STREQ(kExpElementIDs[j], actual.c_str()); ASSERT_STREQ(kExpElementIDs[j], actual.c_str());
ui_controls::SendKeyPressNotifyWhenDone(L'\t', false, false, false, ui_controls::SendKeyPressNotifyWhenDone(L'\t', false, false, false,
...@@ -300,11 +301,12 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusTraversal) { ...@@ -300,11 +301,12 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusTraversal) {
::Sleep(kActionDelayMs); ::Sleep(kActionDelayMs);
// Let's make sure the focus is on the expected element in the page. // Let's make sure the focus is on the expected element in the page.
ui_test_utils::JavaScriptRunner js_runner( std::string actual;
ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
browser()->GetSelectedTabContents()->AsWebContents(), browser()->GetSelectedTabContents()->AsWebContents(),
L"", L"",
L"window.domAutomationController.send(getFocusedElement());"); L"window.domAutomationController.send(getFocusedElement());",
std::string actual = js_runner.Run(); &actual));
ASSERT_STREQ(kExpElementIDs[6 - j], actual.c_str()); ASSERT_STREQ(kExpElementIDs[6 - j], actual.c_str());
} }
......
...@@ -2,19 +2,774 @@ ...@@ -2,19 +2,774 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "net/base/ssl_test_util.h" #include "chrome/browser/browser.h"
#include "chrome/browser/tab_contents/interstitial_page.h"
#include "chrome/browser/tab_contents/navigation_entry.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tab_contents/web_contents.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/pref_service.h"
#include "chrome/test/in_process_browser_test.h" #include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
const wchar_t kDocRoot[] = L"chrome/test/data";
class SSLUITest : public InProcessBrowserTest {
public:
SSLUITest() {
EnableDOMAutomation();
}
scoped_refptr<HTTPTestServer> PlainServer() {
return HTTPTestServer::CreateServer(kDocRoot, NULL);
}
scoped_refptr<HTTPSTestServer> GoodCertServer() {
return HTTPSTestServer::CreateGoodServer(kDocRoot);
}
scoped_refptr<HTTPSTestServer> BadCertServer() {
return HTTPSTestServer::CreateExpiredServer(kDocRoot);
}
namespace { void CheckAuthenticatedState(TabContents* tab,
bool mixed_content,
bool unsafe_content) {
NavigationEntry* entry = tab->controller().GetActiveEntry();
ASSERT_TRUE(entry);
EXPECT_EQ(NavigationEntry::NORMAL_PAGE, entry->page_type());
EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, entry->ssl().security_style());
EXPECT_EQ(0, entry->ssl().cert_status() & net::CERT_STATUS_ALL_ERRORS);
EXPECT_EQ(mixed_content, entry->ssl().has_mixed_content());
EXPECT_EQ(unsafe_content, entry->ssl().has_unsafe_content());
}
const wchar_t* const kDocRoot = L"chrome/test/data"; void CheckUnauthenticatedState(TabContents* tab) {
NavigationEntry* entry = tab->controller().GetActiveEntry();
ASSERT_TRUE(entry);
EXPECT_EQ(NavigationEntry::NORMAL_PAGE, entry->page_type());
EXPECT_EQ(SECURITY_STYLE_UNAUTHENTICATED, entry->ssl().security_style());
EXPECT_EQ(0, entry->ssl().cert_status() & net::CERT_STATUS_ALL_ERRORS);
EXPECT_FALSE(entry->ssl().has_mixed_content());
EXPECT_FALSE(entry->ssl().has_unsafe_content());
}
class SSLBrowserTest : public InProcessBrowserTest { void CheckAuthenticationBrokenState(TabContents* tab,
int error,
bool interstitial) {
NavigationEntry* entry = tab->controller().GetActiveEntry();
ASSERT_TRUE(entry);
EXPECT_EQ(interstitial ? NavigationEntry::INTERSTITIAL_PAGE :
NavigationEntry::NORMAL_PAGE,
entry->page_type());
EXPECT_EQ(SECURITY_STYLE_AUTHENTICATION_BROKEN,
entry->ssl().security_style());
EXPECT_EQ(error, entry->ssl().cert_status() & net::CERT_STATUS_ALL_ERRORS);
EXPECT_FALSE(entry->ssl().has_mixed_content());
EXPECT_FALSE(entry->ssl().has_unsafe_content());
}
private:
DISALLOW_COPY_AND_ASSIGN(SSLUITest);
}; };
} // namespace // Visits a regular page over http.
IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTP) {
scoped_refptr<HTTPTestServer> server = PlainServer();
ui_test_utils::NavigateToURL(browser(),
server->TestServerPageW(L"files/ssl/google.html"));
CheckUnauthenticatedState(browser()->GetSelectedTabContents());
}
// Visits a page over http which includes broken https resources (status should
// be OK).
// TODO(jcampan): test that bad HTTPS content is blocked (otherwise we'll give
// the secure cookies away!).
IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTPWithBrokenHTTPSResource) {
scoped_refptr<HTTPTestServer> http_server = PlainServer();
scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer();
ui_test_utils::NavigateToURL(browser(), http_server->TestServerPageW(
L"files/ssl/page_with_unsafe_contents.html"));
CheckUnauthenticatedState(browser()->GetSelectedTabContents());
}
// Visits a page over OK https:
IN_PROC_BROWSER_TEST_F(SSLUITest, TestOKHTTPS) {
scoped_refptr<HTTPSTestServer> https_server = GoodCertServer();
ui_test_utils::NavigateToURL(browser(),
https_server->TestServerPageW(L"files/ssl/google.html"));
CheckAuthenticatedState(browser()->GetSelectedTabContents(),
false, false); // No mixed/unsafe content.
}
// Visits a page with https error and proceed:
IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTPSExpiredCertAndProceed) {
scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer();
ui_test_utils::NavigateToURL(browser(),
bad_https_server->TestServerPageW(L"files/ssl/google.html"));
TabContents* tab = browser()->GetSelectedTabContents();
CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID,
true); // Interstitial showing
// Proceed through the interstitial.
InterstitialPage* interstitial_page = tab->interstitial_page();
ASSERT_TRUE(interstitial_page);
interstitial_page->Proceed();
// Wait for the navigation to be done.
ui_test_utils::WaitForNavigation(&(tab->controller()));
// TODO(jcampan): port SSLUITest to SSLBrowserTest. CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID,
IN_PROC_BROWSER_TEST_F(SSLBrowserTest, TestHTTP) { false); // No interstitial showing
} }
// Visits a page with https error and don't proceed (and ensure we can still
// navigate at that point):
IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTPSExpiredCertAndDontProceed) {
scoped_refptr<HTTPTestServer> http_server = PlainServer();
scoped_refptr<HTTPSTestServer> good_https_server = GoodCertServer();
scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer();
// First navigate to an OK page.
ui_test_utils::NavigateToURL(browser(), good_https_server->TestServerPageW(
L"files/ssl/google.html"));
TabContents* tab = browser()->GetSelectedTabContents();
NavigationEntry* entry = tab->controller().GetActiveEntry();
ASSERT_TRUE(entry);
GURL cross_site_url =
bad_https_server->TestServerPageW(L"files/ssl/google.html");
// Change the host name from 127.0.0.1 to localhost so it triggers a
// cross-site navigation so we can test http://crbug.com/5800 is gone.
ASSERT_EQ("127.0.0.1", cross_site_url.host());
GURL::Replacements replacements;
std::string new_host("localhost");
replacements.SetHostStr(new_host);
cross_site_url = cross_site_url.ReplaceComponents(replacements);
// Now go to a bad HTTPS page.
ui_test_utils::NavigateToURL(browser(), cross_site_url);
// An interstitial should be showing.
CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID,
true); // Interstitial showing.
// Simulate user clicking "Take me back".
InterstitialPage* interstitial_page = tab->interstitial_page();
ASSERT_TRUE(interstitial_page);
interstitial_page->DontProceed();
// We should be back to the original good page.
CheckAuthenticatedState(tab, false, false);
// Try to navigate to a new page. (to make sure bug 5800 is fixed).
ui_test_utils::NavigateToURL(browser(),
http_server->TestServerPageW(L"files/ssl/google.html"));
CheckUnauthenticatedState(tab);
}
//
// Mixed contents
//
// Visits a page with mixed content.
IN_PROC_BROWSER_TEST_F(SSLUITest, TestMixedContents) {
scoped_refptr<HTTPSTestServer> https_server = GoodCertServer();
scoped_refptr<HTTPTestServer> http_server = PlainServer();
// Load a page with mixed-content, the default behavior is to show the mixed
// content.
ui_test_utils::NavigateToURL(browser(), https_server->TestServerPageW(
L"files/ssl/page_with_mixed_contents.html"));
CheckAuthenticatedState(browser()->GetSelectedTabContents(),
true /* mixed-content */, false);
}
// Visits a page with mixed content.
IN_PROC_BROWSER_TEST_F(SSLUITest, TestMixedContentsFilterAll) {
scoped_refptr<HTTPSTestServer> https_server = GoodCertServer();
scoped_refptr<HTTPTestServer> http_server = PlainServer();
// Set the "block mixed-content" preference.
browser()->profile()->GetPrefs()->SetInteger(prefs::kMixedContentFiltering,
FilterPolicy::FILTER_ALL);
// Load a page with mixed-content, the mixed content shouldn't load.
ui_test_utils::NavigateToURL(browser(), https_server->TestServerPageW(
L"files/ssl/page_with_mixed_contents.html"));
TabContents* tab = browser()->GetSelectedTabContents();
NavigationEntry* entry = tab->controller().GetActiveEntry();
ASSERT_TRUE(entry);
EXPECT_EQ(NavigationEntry::NORMAL_PAGE, entry->page_type());
// The image should be filtered.
int img_width = 0;
EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractInt(
tab, L"", L"window.domAutomationController.send(ImageWidth());",
&img_width));
// In order to check that the image was not loaded, we check its width.
// The actual image (Google logo) is 114 pixels wide, we assume the broken
// image is less than 100.
EXPECT_GT(100, img_width);
// The state should be OK since we are not showing the resource.
CheckAuthenticatedState(tab, false, false);
// There should be one info-bar to show the mixed-content.
EXPECT_EQ(1, tab->infobar_delegate_count());
// Activate the link on the info-bar to show the mixed-content.
InfoBarDelegate* delegate = tab->GetInfoBarDelegateAt(0);
ASSERT_TRUE(delegate->AsConfirmInfoBarDelegate());
delegate->AsConfirmInfoBarDelegate()->Accept();
// Showing the mixed-contents triggered a page reload, let's wait for it to
// finish.
ui_test_utils::WaitForNavigation(&(tab->controller()));
// The image should show now.
EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractInt(
tab, L"", L"window.domAutomationController.send(ImageWidth());",
&img_width));
EXPECT_LT(100, img_width);
// And our status should be mixed-content.
CheckAuthenticatedState(tab, true /* mixed-content */, false);
}
// Visits a page with an http script that tries to suppress our mixed content
// warnings by randomize location.hash.
// Based on http://crbug.com/8706
IN_PROC_BROWSER_TEST_F(SSLUITest, TestMixedContentsRandomizeHash) {
scoped_refptr<HTTPSTestServer> https_server = GoodCertServer();
scoped_refptr<HTTPTestServer> http_server = PlainServer();
ui_test_utils::NavigateToURL(browser(), https_server->TestServerPageW(
L"files/ssl/page_with_http_script.html"));
CheckAuthenticatedState(browser()->GetSelectedTabContents(),
true /* mixed-content */, false);
}
// Visits a page with unsafe content and make sure that:
// - frames content is replaced with warning
// - images and scripts are filtered out entirely
IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeContents) {
scoped_refptr<HTTPSTestServer> good_https_server = GoodCertServer();
scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer();
ui_test_utils::NavigateToURL(browser(), good_https_server->TestServerPageW(
L"files/ssl/page_with_unsafe_contents.html"));
TabContents* tab = browser()->GetSelectedTabContents();
// When the bad content is filtered, the state is expected to be
// authenticated.
CheckAuthenticatedState(tab, false, false);
// Because of cross-frame scripting restrictions, we cannot access the iframe
// content. So to know if the frame was loaded, we just check if a popup was
// opened (the iframe content opens one).
// Note: because of bug 1115868, no constrained window is opened right now.
// Once the bug is fixed, this will do the real check.
EXPECT_EQ(0, tab->constrained_window_count());
int img_width;
EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractInt(
tab, L"", L"window.domAutomationController.send(ImageWidth());",
&img_width));
// In order to check that the image was not loaded, we check its width.
// The actual image (Google logo) is 114 pixels wide, we assume the broken
// image is less than 100.
EXPECT_GT(100, img_width);
bool js_result = false;
EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
tab, L"", L"window.domAutomationController.send(IsFooSet());",
&js_result));
EXPECT_FALSE(js_result);
}
// Visits a page with mixed content loaded by JS (after the initial page load).
IN_PROC_BROWSER_TEST_F(SSLUITest, TestMixedContentsLoadedFromJS) {
scoped_refptr<HTTPSTestServer> https_server = GoodCertServer();
scoped_refptr<HTTPTestServer> http_server = PlainServer();
ui_test_utils::NavigateToURL(browser(), https_server->TestServerPageW(
L"files/ssl/page_with_dynamic_mixed_contents.html"));
TabContents* tab = browser()->GetSelectedTabContents();
CheckAuthenticatedState(tab, false, false);
// Load the insecure image.
bool js_result = false;
EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
tab, L"", L"loadBadImage();", &js_result));
EXPECT_TRUE(js_result);
// We should now have mixed-contents.
CheckAuthenticatedState(tab, true /* mixed-content */, false);
}
// Visits two pages from the same origin: one with mixed content and one
// without. The test checks that we propagate the mixed content state from one
// to the other.
IN_PROC_BROWSER_TEST_F(SSLUITest, TestMixedContentsTwoTabs) {
scoped_refptr<HTTPSTestServer> https_server = GoodCertServer();
scoped_refptr<HTTPTestServer> http_server = PlainServer();
ui_test_utils::NavigateToURL(browser(),
https_server->TestServerPageW(L"files/ssl/blank_page.html"));
TabContents* tab1 = browser()->GetSelectedTabContents();
// This tab should be fine.
CheckAuthenticatedState(tab1, false, false);
// Create a new tab.
GURL url =
https_server->TestServerPageW(L"files/ssl/page_with_http_script.html");
TabContents* tab2 = browser()->AddTabWithURL(url,
GURL(),
PageTransition::TYPED, true, 0,
NULL);
ui_test_utils::WaitForNavigation(&(tab2->controller()));
// The new tab has mixed content.
CheckAuthenticatedState(tab2, true /* mixed-content */, false);
// Which means the origin for the first tab has also been contaminated with
// mixed content.
CheckAuthenticatedState(tab1, true /* mixed-content */, false);
}
// Visits a page with an image over http. Visits another page over https
// referencing that same image over http (hoping it is coming from the webcore
// memory cache).
IN_PROC_BROWSER_TEST_F(SSLUITest, TestCachedMixedContents) {
scoped_refptr<HTTPSTestServer> https_server = GoodCertServer();
scoped_refptr<HTTPTestServer> http_server = PlainServer();
ui_test_utils::NavigateToURL(browser(), http_server->TestServerPageW(
L"files/ssl/page_with_mixed_contents.html"));
TabContents* tab = browser()->GetSelectedTabContents();
CheckUnauthenticatedState(tab);
// Load again but over SSL. It should have mixed-contents (even though the
// image comes from the WebCore memory cache).
ui_test_utils::NavigateToURL(browser(), https_server->TestServerPageW(
L"files/ssl/page_with_mixed_contents.html"));
CheckAuthenticatedState(tab, true /* mixed-content */, false);
}
// This test ensures the CN invalid status does not 'stick' to a certificate
// (see bug #1044942) and that it depends on the host-name.
IN_PROC_BROWSER_TEST_F(SSLUITest, TestCNInvalidStickiness) {
const std::string kLocalHost = "localhost";
scoped_refptr<HTTPSTestServer> https_server =
HTTPSTestServer::CreateMismatchedServer(kDocRoot);
ASSERT_TRUE(NULL != https_server.get());
// First we hit the server with hostname, this generates an invalid policy
// error.
ui_test_utils::NavigateToURL(browser(),
https_server->TestServerPageW(L"files/ssl/google.html"));
// We get an interstitial page as a result.
TabContents* tab = browser()->GetSelectedTabContents();
CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID,
true); // Interstitial showing.
// We proceed through the interstitial page.
InterstitialPage* interstitial_page = tab->interstitial_page();
ASSERT_TRUE(interstitial_page);
interstitial_page->Proceed();
// Wait for the navigation to be done.
ui_test_utils::WaitForNavigation(&(tab->controller()));
CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID,
false); // No interstitial showing.
// Now we try again with the right host name this time.
// Let's change the host-name in the url.
GURL url = https_server->TestServerPageW(L"files/ssl/google.html");
std::string::size_type hostname_index = url.spec().find(kLocalHost);
ASSERT_TRUE(hostname_index != std::string::npos); // Test sanity check.
std::string new_url;
new_url.append(url.spec().substr(0, hostname_index));
new_url.append(net::TestServerLauncher::kHostName);
new_url.append(url.spec().substr(hostname_index + kLocalHost.size()));
ui_test_utils::NavigateToURL(browser(), GURL(new_url));
// Security state should be OK.
CheckAuthenticatedState(tab, false, false);
// Now try again the broken one to make sure it is still broken.
ui_test_utils::NavigateToURL(browser(),
https_server->TestServerPageW(L"files/ssl/google.html"));
// Since we OKed the interstitial last time, we get right to the page.
CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID,
false); // No interstitial showing.
}
// Test that navigating to a #ref does not change a bad security state.
IN_PROC_BROWSER_TEST_F(SSLUITest, TestRefNavigation) {
scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer();
ui_test_utils::NavigateToURL(browser(),
bad_https_server->TestServerPageW(L"files/ssl/page_with_refs.html"));
TabContents* tab = browser()->GetSelectedTabContents();
CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID,
true); // Interstitial showing.
InterstitialPage* interstitial_page = tab->interstitial_page();
ASSERT_TRUE(interstitial_page);
interstitial_page->Proceed();
// Wait for the navigation to be done.
ui_test_utils::WaitForNavigation(&(tab->controller()));
CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID,
false); // No interstitial showing.
// Now navigate to a ref in the page, the security state should not have
// changed.
ui_test_utils::NavigateToURL(browser(),
bad_https_server->TestServerPageW(L"files/ssl/page_with_refs.html#jp"));
CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID,
false); // No interstitial showing.
}
// Tests that closing a page that has a unsafe pop-up does not crash the browser
// (bug #1966).
IN_PROC_BROWSER_TEST_F(SSLUITest, TestCloseTabWithUnsafePopup) {
scoped_refptr<HTTPTestServer> http_server = PlainServer();
scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer();
ui_test_utils::NavigateToURL(browser(), http_server->TestServerPageW(
L"files/ssl/page_with_unsafe_popup.html"));
TabContents* tab1 = browser()->GetSelectedTabContents();
// It is probably overkill to add a notification for a popup-opening, let's
// just poll.
for (int i = 0; i < 10; i++) {
if (tab1->constrained_window_count() > 0)
break;
MessageLoop::current()->PostDelayedTask(FROM_HERE,
new MessageLoop::QuitTask(), 1000);
ui_test_utils::RunMessageLoop();
}
ASSERT_EQ(1, tab1->constrained_window_count());
// Let's add another tab to make sure the browser does not exit when we close
// the first tab.
GURL url = http_server->TestServerPageW(L"files/ssl/google.html");
TabContents* tab2 = browser()->AddTabWithURL(url,
GURL(),
PageTransition::TYPED,
true, 0, NULL);
ui_test_utils::WaitForNavigation(&(tab2->controller()));
// Close the first tab.
browser()->CloseTabContents(tab1);
}
// Visit a page over bad https that is a redirect to a page with good https.
IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectBadToGoodHTTPS) {
scoped_refptr<HTTPSTestServer> good_https_server = GoodCertServer();
scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer();
GURL url1 = bad_https_server->TestServerPageW(L"server-redirect?");
GURL url2 = good_https_server->TestServerPageW(L"files/ssl/google.html");
ui_test_utils::NavigateToURL(browser(), GURL(url1.spec() + url2.spec()));
TabContents* tab = browser()->GetSelectedTabContents();
CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID,
true); // Interstitial showing.
// We proceed through the interstitial page.
InterstitialPage* interstitial_page = tab->interstitial_page();
ASSERT_TRUE(interstitial_page);
interstitial_page->Proceed();
// Wait for the navigation to be done.
ui_test_utils::WaitForNavigation(&(tab->controller()));
// We have been redirected to the good page.
CheckAuthenticatedState(tab, false, false); // No mixed/unsafe content.
}
// Visit a page over good https that is a redirect to a page with bad https.
IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectGoodToBadHTTPS) {
scoped_refptr<HTTPSTestServer> good_https_server = GoodCertServer();
scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer();
GURL url1 = good_https_server->TestServerPageW(L"server-redirect?");
GURL url2 = bad_https_server->TestServerPageW(L"files/ssl/google.html");
ui_test_utils::NavigateToURL(browser(), GURL(url1.spec() + url2.spec()));
TabContents* tab = browser()->GetSelectedTabContents();
CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID,
true); // Interstitial showing.
// We proceed through the interstitial page.
InterstitialPage* interstitial_page = tab->interstitial_page();
ASSERT_TRUE(interstitial_page);
interstitial_page->Proceed();
// Wait for the navigation to be done.
ui_test_utils::WaitForNavigation(&(tab->controller()));
CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID,
false); // No interstitial showing.
}
// Visit a page over http that is a redirect to a page with good HTTPS.
IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectHTTPToGoodHTTPS) {
scoped_refptr<HTTPTestServer> http_server = PlainServer();
scoped_refptr<HTTPSTestServer> good_https_server = GoodCertServer();
TabContents* tab = browser()->GetSelectedTabContents();
// HTTP redirects to good HTTPS.
GURL http_url = http_server->TestServerPageW(L"server-redirect?");
GURL good_https_url =
good_https_server->TestServerPageW(L"files/ssl/google.html");
ui_test_utils::NavigateToURL(browser(),
GURL(http_url.spec() + good_https_url.spec()));
CheckAuthenticatedState(tab, false, false); // No mixed/unsafe content.
}
// Visit a page over http that is a redirect to a page with bad HTTPS.
IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectHTTPToBadHTTPS) {
scoped_refptr<HTTPTestServer> http_server = PlainServer();
scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer();
TabContents* tab = browser()->GetSelectedTabContents();
GURL http_url = http_server->TestServerPageW(L"server-redirect?");
GURL bad_https_url =
bad_https_server->TestServerPageW(L"files/ssl/google.html");
ui_test_utils::NavigateToURL(browser(),
GURL(http_url.spec() + bad_https_url.spec()));
CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID,
true); // Interstitial showing.
// Continue on the interstitial.
InterstitialPage* interstitial_page = tab->interstitial_page();
ASSERT_TRUE(interstitial_page);
interstitial_page->Proceed();
// Wait for the navigation to be done.
ui_test_utils::WaitForNavigation(&(tab->controller()));
CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID,
false); // No interstitial showing.
}
// Visit a page over https that is a redirect to a page with http (to make sure
// we don't keep the secure state).
IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectHTTPSToHTTP) {
scoped_refptr<HTTPTestServer> http_server = PlainServer();
scoped_refptr<HTTPSTestServer> https_server = GoodCertServer();
GURL https_url = https_server->TestServerPageW(L"server-redirect?");
GURL http_url = http_server->TestServerPageW(L"files/ssl/google.html");
ui_test_utils::NavigateToURL(browser(),
GURL(https_url.spec() + http_url.spec()));
CheckUnauthenticatedState(browser()->GetSelectedTabContents());
}
// Visits a page to which we could not connect (bad port) over http and https
// and make sure the security style is correct.
IN_PROC_BROWSER_TEST_F(SSLUITest, TestConnectToBadPort) {
ui_test_utils::NavigateToURL(browser(), GURL("http://localhost:17"));
CheckUnauthenticatedState(browser()->GetSelectedTabContents());
// Same thing over HTTPS.
ui_test_utils::NavigateToURL(browser(), GURL("https://localhost:17"));
CheckUnauthenticatedState(browser()->GetSelectedTabContents());
}
//
// Frame navigation
//
// From a good HTTPS top frame:
// - navigate to an OK HTTPS frame
// - navigate to a bad HTTPS (expect unsafe content and filtered frame), then
// back
// - navigate to HTTP (expect mixed content), then back
IN_PROC_BROWSER_TEST_F(SSLUITest, TestGoodFrameNavigation) {
scoped_refptr<HTTPTestServer> http_server = PlainServer();
scoped_refptr<HTTPSTestServer> good_https_server = GoodCertServer();
scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer();
TabContents* tab = browser()->GetSelectedTabContents();
ui_test_utils::NavigateToURL(
browser(),
good_https_server->TestServerPageW(L"files/ssl/top_frame.html"));
CheckAuthenticatedState(tab, false, false);
bool success = false;
// Now navigate inside the frame.
EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(tab,
L"",
L"window.domAutomationController.send(clickLink('goodHTTPSLink'));",
&success));
EXPECT_TRUE(success);
ui_test_utils::WaitForNavigation(&tab->controller());
// We should still be fine.
CheckAuthenticatedState(tab, false, false);
// Now let's hit a bad page.
EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(tab,
L"",
L"window.domAutomationController.send(clickLink('badHTTPSLink'));",
&success));
EXPECT_TRUE(success);
ui_test_utils::WaitForNavigation(&tab->controller());
// The security style should still be secure.
CheckAuthenticatedState(tab, false, false);
// And the frame should be blocked.
bool is_content_evil = true;
std::wstring content_frame_xpath(L"html/frameset/frame[2]");
std::wstring is_frame_evil_js(
L"window.domAutomationController"
L".send(document.getElementById('evilDiv') != null);");
EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(tab,
content_frame_xpath,
is_frame_evil_js,
&is_content_evil));
EXPECT_FALSE(is_content_evil);
// Now go back, our state should still be OK.
tab->controller().GoBack();
ui_test_utils::WaitForNavigation(&tab->controller());
CheckAuthenticatedState(tab, false, false);
// Navigate to a page served over HTTP.
EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(tab,
L"",
L"window.domAutomationController.send(clickLink('HTTPLink'));",
&success));
EXPECT_TRUE(success);
ui_test_utils::WaitForNavigation(&tab->controller());
// Our state should be mixed-content.
CheckAuthenticatedState(tab, true, false);
// Go back, our state should be unchanged.
tab->controller().GoBack();
ui_test_utils::WaitForNavigation(&tab->controller());
CheckAuthenticatedState(tab, true, false);
}
// From a bad HTTPS top frame:
// - navigate to an OK HTTPS frame (expected to be still authentication broken).
IN_PROC_BROWSER_TEST_F(SSLUITest, TestBadFrameNavigation) {
scoped_refptr<HTTPSTestServer> good_https_server = GoodCertServer();
scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer();
TabContents* tab = browser()->GetSelectedTabContents();
ui_test_utils::NavigateToURL(
browser(),
bad_https_server->TestServerPageW(L"files/ssl/top_frame.html"));
CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID,
true); // Interstitial showing
// Continue on the interstitial.
InterstitialPage* interstitial_page = tab->interstitial_page();
ASSERT_TRUE(interstitial_page);
interstitial_page->Proceed();
// Wait for the navigation to be done.
ui_test_utils::WaitForNavigation(&(tab->controller()));
// Navigate to a good frame.
bool success = false;
EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(tab,
L"",
L"window.domAutomationController.send(clickLink('goodHTTPSLink'));",
&success));
EXPECT_TRUE(success);
ui_test_utils::WaitForNavigation(&tab->controller());
// We should still be authentication broken.
CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false);
}
// From an HTTP top frame, navigate to good and bad HTTPS (security state should
// stay unauthenticated).
IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnauthenticatedFrameNavigation) {
scoped_refptr<HTTPTestServer> http_server = PlainServer();
scoped_refptr<HTTPSTestServer> good_https_server = GoodCertServer();
scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer();
TabContents* tab = browser()->GetSelectedTabContents();
ui_test_utils::NavigateToURL(
browser(),
http_server->TestServerPageW(L"files/ssl/top_frame.html"));
CheckUnauthenticatedState(tab);
// Now navigate inside the frame to a secure HTTPS frame.
bool success = false;
EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(tab,
L"",
L"window.domAutomationController.send(clickLink('goodHTTPSLink'));",
&success));
EXPECT_TRUE(success);
ui_test_utils::WaitForNavigation(&tab->controller());
// We should still be unauthenticated.
CheckUnauthenticatedState(tab);
// Now navigate to a bad HTTPS frame.
EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(tab,
L"",
L"window.domAutomationController.send(clickLink('badHTTPSLink'));",
&success));
EXPECT_TRUE(success);
ui_test_utils::WaitForNavigation(&tab->controller());
// State should not have changed.
CheckUnauthenticatedState(tab);
// And the frame should have been blocked (see bug #2316).
bool is_content_evil = true;
std::wstring content_frame_xpath(L"html/frameset/frame[2]");
std::wstring is_frame_evil_js(
L"window.domAutomationController"
L".send(document.getElementById('evilDiv') != null);");
EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(tab,
content_frame_xpath, is_frame_evil_js, &is_content_evil));
EXPECT_FALSE(is_content_evil);
}
// TODO(jcampan): more tests to do below.
// Visit a page over https that contains a frame with a redirect.
// XMLHttpRequest mixed in synchronous mode.
// XMLHttpRequest mixed in asynchronous mode.
// XMLHttpRequest over bad ssl in synchronous mode.
// XMLHttpRequest over OK ssl in synchronous mode.
...@@ -100,7 +100,7 @@ class NavigationEntry { ...@@ -100,7 +100,7 @@ class NavigationEntry {
// Raw accessors for all the content status flags. This contains a // Raw accessors for all the content status flags. This contains a
// combination of any of the ContentStatusFlags defined above. It is used // combination of any of the ContentStatusFlags defined above. It is used
// by the UI tests for checking and for certain copying. Use the per-status // by some tests for checking and for certain copying. Use the per-status
// functions for normal usage. // functions for normal usage.
void set_content_status(int content_status) { void set_content_status(int content_status) {
content_status_ = content_status; content_status_ = content_status;
...@@ -120,7 +120,7 @@ class NavigationEntry { ...@@ -120,7 +120,7 @@ class NavigationEntry {
// Copy and assignment is explicitly allowed for this class. // Copy and assignment is explicitly allowed for this class.
}; };
// The type of the page an entry corresponds to. Used by ui tests. // The type of the page an entry corresponds to. Used by tests.
enum PageType { enum PageType {
NORMAL_PAGE = 0, NORMAL_PAGE = 0,
ERROR_PAGE, ERROR_PAGE,
......
...@@ -358,6 +358,9 @@ class TabContents : public PageNavigator, ...@@ -358,6 +358,9 @@ class TabContents : public PageNavigator,
// Called when the blocked popup notification is shown or hidden. // Called when the blocked popup notification is shown or hidden.
virtual void PopupNotificationVisibilityChanged(bool visible); virtual void PopupNotificationVisibilityChanged(bool visible);
// Returns the number of constrained windows in this tab. Used by tests.
size_t constrained_window_count() { return child_windows_.size(); }
// Views and focus ----------------------------------------------------------- // Views and focus -----------------------------------------------------------
// TODO(brettw): Most of these should be removed and the caller should call // TODO(brettw): Most of these should be removed and the caller should call
// the view directly. // the view directly.
......
...@@ -149,11 +149,13 @@ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindInPageFrames) { ...@@ -149,11 +149,13 @@ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindInPageFrames) {
} }
std::string FocusedOnPage(WebContents* web_contents) { std::string FocusedOnPage(WebContents* web_contents) {
ui_test_utils::JavaScriptRunner js_runner( std::string result;
ui_test_utils::ExecuteJavaScriptAndExtractString(
web_contents, web_contents,
L"", L"",
L"window.domAutomationController.send(getFocusedElement());"); L"window.domAutomationController.send(getFocusedElement());",
return js_runner.Run(); &result);
return result;
} }
// This tests the FindInPage end-state, in other words: what is focused when you // This tests the FindInPage end-state, in other words: what is focused when you
...@@ -186,11 +188,12 @@ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindInPageEndState) { ...@@ -186,11 +188,12 @@ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindInPageEndState) {
EXPECT_EQ(1, FindInPage(L"Google", FWD, IGNORE_CASE, false)); EXPECT_EQ(1, FindInPage(L"Google", FWD, IGNORE_CASE, false));
// Move the selection to link 1, after searching. // Move the selection to link 1, after searching.
ui_test_utils::JavaScriptRunner js_runner( std::string result;
ui_test_utils::ExecuteJavaScriptAndExtractString(
web_contents, web_contents,
L"", L"",
L"window.domAutomationController.send(selectLink1());"); L"window.domAutomationController.send(selectLink1());",
js_runner.Run(); &result);
// End the find session. // End the find session.
web_contents->StopFinding(false); web_contents->StopFinding(false);
......
<html><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"><title>Google</title><style>body,td,a,p,.h{font-family:arial,sans-serif}.h{font-size:20px}.h{color:#3366cc}.q{color:#00c}.ts td{padding:0}.ts{border-collapse:collapse}#gbar{float:left;font-weight:bold;height:22px;padding-left:2px}.gbh,.gb2 div{border-top:1px solid #c9d7f1;font-size:0;height:0}.gbh{position:absolute;top:24px;width:100%}.gb2 div{margin:5px}#gbi{background:#fff;border:1px solid;border-color:#c9d7f1 #36c #36c #a2bae7;font-size:13px;top:24px;z-index:1000}#guser{padding-bottom:7px !important}#gbar,#guser{font-size:13px;padding-top:1px !important}@media all{.gb1,.gb3{height:22px;margin-right:.73em;vertical-align:top}.gb2 a{display:block;padding:.2em .5em}}#gbi,.gb2{display:none;position:absolute;width:8em}.gb2{z-index:1001}#gbar a,#gbar a:active,#gbar a:visited{color:#00c;font-weight:normal}.gb2 a,.gb3 a{text-decoration:none}#gbar .gb2 a:hover{background:#36c;color:#fff;display:block}</style><script>window.google={kEI:"BuG9R7b_PI6SoASYhdTtDQ",kEXPI:"17259,17735,17870",kHL:"en"}; <html><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"><title>Google</title><style>body,td,a,p,.h{font-family:arial,sans-serif}.h{font-size:20px}.h{color:#3366cc}.q{color:#00c}.ts td{padding:0}.ts{border-collapse:collapse}#gbar{float:left;font-weight:bold;height:22px;padding-left:2px}.gbh,.gb2 div{border-top:1px solid #c9d7f1;font-size:0;height:0}.gbh{position:absolute;top:24px;width:100%}.gb2 div{margin:5px}#gbi{background:#fff;border:1px solid;border-color:#c9d7f1 #36c #36c #a2bae7;font-size:13px;top:24px;z-index:1000}#guser{padding-bottom:7px !important}#gbar,#guser{font-size:13px;padding-top:1px !important}@media all{.gb1,.gb3{height:22px;margin-right:.73em;vertical-align:top}.gb2 a{display:block;padding:.2em .5em}}#gbi,.gb2{display:none;position:absolute;width:8em}.gb2{z-index:1001}#gbar a,#gbar a:active,#gbar a:visited{color:#00c;font-weight:normal}.gb2 a,.gb3 a{text-decoration:none}#gbar .gb2 a:hover{background:#36c;color:#fff;display:block}</style><script>window.google={kEI:"BuG9R7b_PI6SoASYhdTtDQ",kEXPI:"17259,17735,17870",kHL:"en"};
function sf(){document.f.q.focus()} function sf(){document.f.q.focus()}
window.rwt=function(b,d,e,g,h,f,i){var a=encodeURIComponent||escape,c=b.href.split("#");b.href="/url?sa=t"+(d?"&oi="+a(d):"")+(e?"&cad="+a(e):"")+"&ct="+a(g)+"&cd="+a(h)+"&url="+a(c[0]).replace(/\+/g,"%2B")+"&ei=BuG9R7b_PI6SoASYhdTtDQ"+(f?"&usg="+f:"")+i+(c[1]?"#"+c[1]:"");b.onmousedown="";return true}; window.rwt=function(b,d,e,g,h,f,i){var a=encodeURIComponent||escape,c=b.href.split("#");b.href="/url?sa=t"+(d?"&oi="+a(d):"")+(e?"&cad="+a(e):"")+"&ct="+a(g)+"&cd="+a(h)+"&url="+a(c[0]).replace(/\+/g,"%2B")+"&ei=BuG9R7b_PI6SoASYhdTtDQ"+(f?"&usg="+f:"")+i+(c[1]?"#"+c[1]:"");b.onmousedown="";return true};
window.gbar={};(function(){var a=window.gbar,b,g,h;function l(c,f,e){c.display=h?"none":"block";c.left=f+"px";c.top=e+"px"}a.tg=function(c){var f=0,e=0,d,m=0,n,j=window.navExtra,k,i=document;g=g||i.getElementById("gbar").getElementsByTagName("span");(c||window.event).cancelBubble=!m;if(!b){b=i.createElement(Array.every||window.createPopup?"iframe":"DIV");b.frameBorder="0";b.scrolling="no";b.src="#";g[7].parentNode.appendChild(b).id="gbi";if(j&&g[7])for(n in j){k=i.createElement("span");k.appendChild(j[n]);g[7].parentNode.insertBefore(k,g[7]).className="gb2"}i.onclick=a.close}while(d=g[++m]){if(e){l(d.style,e+1,f+25);f+=d.firstChild.tagName=="DIV"?9:20}if(d.className=="gb3"){do e+=d.offsetLeft;while(d=d.offsetParent)}}b.style.height=f+"px";l(b.style,e,24);h=!h};a.close=function(c){h&&a.tg(c)}})();</script></head><body onload="sf();if(document.images){new Image().src='/images/nav_logo3.png'}" topmargin="3" alink="#ff0000" bgcolor="#ffffff" link="#0000cc" marginheight="3" text="#000000" vlink="#551a8b"><div id="gbar"><nobr><span class="gb1">Web</span> <span class="gb1"><a href="http://images.google.com/imghp?hl=en&amp;tab=wi">Images</a></span> <span class="gb1"><a href="http://maps.google.com/maps?hl=en&amp;tab=wl">Maps</a></span> <span class="gb1"><a href="http://news.google.com/nwshp?hl=en&amp;tab=wn">News</a></span> <span class="gb1"><a href="http://www.google.com/prdhp?hl=en&amp;tab=wf">Shopping</a></span> <span class="gb1"><a href="http://mail.google.com/mail/?hl=en&amp;tab=wm">Gmail</a></span> <span class="gb3"><a href="http://www.google.com/intl/en/options/" onclick="this.blur();gbar.tg(event);return !1"><u>more</u> <small></small></a></span> <span class="gb2"><a href="http://video.google.com/?hl=en&amp;tab=wv">Video</a></span> <span class="gb2"><a href="http://groups.google.com/grphp?hl=en&amp;tab=wg">Groups</a></span> <span class="gb2"><a href="http://books.google.com/bkshp?hl=en&amp;tab=wp">Books</a></span> <span class="gb2"><a href="http://scholar.google.com/schhp?hl=en&amp;tab=ws">Scholar</a></span> <span class="gb2"><a href="http://finance.google.com/finance?hl=en&amp;tab=we">Finance</a></span> <span class="gb2"><a href="http://blogsearch.google.com/?hl=en&amp;tab=wb">Blogs</a></span> <span class="gb2"><div></div></span> <span class="gb2"><a href="http://www.youtube.com/?hl=en&amp;tab=w1">YouTube</a></span> <span class="gb2"><a href="http://www.google.com/calendar/render?hl=en&amp;tab=wc">Calendar</a></span> <span class="gb2"><a href="http://picasaweb.google.com/home?hl=en&amp;tab=wq">Photos</a></span> <span class="gb2"><a href="http://docs.google.com/?hl=en&amp;tab=wo">Documents</a></span> <span class="gb2"><a href="http://www.google.com/reader/view/?hl=en&amp;tab=wy">Reader</a></span> <span class="gb2"><div></div></span> <span class="gb2"><a href="http://www.google.com/intl/en/options/">even more »</a></span> </nobr></div><div class="gbh" style="left: 0pt;"></div><div class="gbh" style="right: 0pt;"></div><div id="guser" style="padding: 0pt 0pt 4px; font-size: 84%;" width="100%" align="right"><nobr><b>jcampan@gmail.com</b> | <a href="http://www.google.com/url?sa=p&amp;pref=ig&amp;pval=3&amp;q=http://www.google.com/ig%3Fhl%3Den%26source%3Diglk&amp;usg=AFQjCNFA18XPfgb7dKnXfKz7x7g1GDH1tg">iGoogle</a> | <a href="https://www.google.com/accounts/ManageAccount">My Account</a> | <a href="http://www.google.com/accounts/Logout?continue=http://www.google.com/">Sign out</a></nobr></div><center><br id="lgpd" clear="all"><img alt="Google" src="google_files/logo.gif" height="110" width="276"><br><br><form action="/search" name="f"><table cellpadding="0" cellspacing="0"><tbody><tr valign="top"><td width="25%">&nbsp;</td><td align="center" nowrap="nowrap"><input name="hl" value="en" type="hidden"><input maxlength="2048" name="q" size="55" title="Google Search" value=""><br><input name="btnG" value="Google Search" type="submit"><input name="btnI" value="I'm Feeling Lucky" type="submit"></td><td nowrap="nowrap" width="25%"><font size="-2">&nbsp;&nbsp;<a href="http://www.google.com/advanced_search?hl=en">Advanced Search</a><br>&nbsp;&nbsp;<a href="http://www.google.com/preferences?hl=en">Preferences</a><br>&nbsp;&nbsp;<a href="http://www.google.com/language_tools?hl=en">Language Tools</a></font></td></tr></tbody></table></form><br><br><font size="-1"><a href="http://www.google.com/intl/en/ads/">Advertising&nbsp;Programs</a> - <a href="http://www.google.com/services/">Business Solutions</a> - <a href="http://www.google.com/intl/en/about.html">About Google</a></font><p><font size="-2">©2008 Google</font></p></center></body></html> window.gbar={};(function(){var a=window.gbar,b,g,h;function l(c,f,e){c.display=h?"none":"block";c.left=f+"px";c.top=e+"px"}a.tg=function(c){var f=0,e=0,d,m=0,n,j=window.navExtra,k,i=document;g=g||i.getElementById("gbar").getElementsByTagName("span");(c||window.event).cancelBubble=!m;if(!b){b=i.createElement(Array.every||window.createPopup?"iframe":"DIV");b.frameBorder="0";b.scrolling="no";b.src="#";g[7].parentNode.appendChild(b).id="gbi";if(j&&g[7])for(n in j){k=i.createElement("span");k.appendChild(j[n]);g[7].parentNode.insertBefore(k,g[7]).className="gb2"}i.onclick=a.close}while(d=g[++m]){if(e){l(d.style,e+1,f+25);f+=d.firstChild.tagName=="DIV"?9:20}if(d.className=="gb3"){do e+=d.offsetLeft;while(d=d.offsetParent)}}b.style.height=f+"px";l(b.style,e,24);h=!h};a.close=function(c){h&&a.tg(c)}})();</script></head><body onload="sf();if(document.images){new Image().src='/images/nav_logo3.png'}" topmargin="3" alink="#ff0000" bgcolor="#ffffff" link="#0000cc" marginheight="3" text="#000000" vlink="#551a8b"><div id="gbar"><nobr><span class="gb1">Web</span> <span class="gb1"><a href="imghp?hl=en&amp;tab=wi">Images</a></span> <span class="gb1"><a href="maps?hl=en&amp;tab=wl">Maps</a></span> <span class="gb1"><a href="nwshp?hl=en&amp;tab=wn">News</a></span> <span class="gb1"><a href="prdhp?hl=en&amp;tab=wf">Shopping</a></span> <span class="gb1"><a href="mail/?hl=en&amp;tab=wm">Gmail</a></span> <span class="gb3"><a href="intl/en/options/" onclick="this.blur();gbar.tg(event);return !1"><u>more</u> <small></small></a></span> <span class="gb2"><a href="?hl=en&amp;tab=wv">Video</a></span> <span class="gb2"><a href="grphp?hl=en&amp;tab=wg">Groups</a></span> <span class="gb2"><a href="bkshp?hl=en&amp;tab=wp">Books</a></span> <span class="gb2"><a href="schhp?hl=en&amp;tab=ws">Scholar</a></span> <span class="gb2"><a href="finance?hl=en&amp;tab=we">Finance</a></span> <span class="gb2"><a href="?hl=en&amp;tab=wb">Blogs</a></span> <span class="gb2"><div></div></span> <span class="gb2"><a href="?hl=en&amp;tab=w1">YouTube</a></span> <span class="gb2"><a href="calendar/render?hl=en&amp;tab=wc">Calendar</a></span> <span class="gb2"><a href="home?hl=en&amp;tab=wq">Photos</a></span> <span class="gb2"><a href="?hl=en&amp;tab=wo">Documents</a></span> <span class="gb2"><a href="reader/view/?hl=en&amp;tab=wy">Reader</a></span> <span class="gb2"><div></div></span> <span class="gb2"><a href="intl/en/options/">even more »</a></span> </nobr></div><div class="gbh" style="left: 0pt;"></div><div class="gbh" style="right: 0pt;"></div><div id="guser" style="padding: 0pt 0pt 4px; font-size: 84%;" width="100%" align="right"><nobr><b>jcampan@gmail.com</b> | <a href="url?sa=p&amp;pref=ig&amp;pval=3&amp;q=ig%3Fhl%3Den%26source%3Diglk&amp;usg=AFQjCNFA18XPfgb7dKnXfKz7x7g1GDH1tg">iGoogle</a> | <a href="https://www.google.com/accounts/ManageAccount">My Account</a> | <a href="accounts/Logout?continue=">Sign out</a></nobr></div><center><br id="lgpd" clear="all"><img alt="Google" src="google_files/logo.gif" height="110" width="276"><br><br><form action="/search" name="f"><table cellpadding="0" cellspacing="0"><tbody><tr valign="top"><td width="25%">&nbsp;</td><td align="center" nowrap="nowrap"><input name="hl" value="en" type="hidden"><input maxlength="2048" name="q" size="55" title="Google Search" value=""><br><input name="btnG" value="Google Search" type="submit"><input name="btnI" value="I'm Feeling Lucky" type="submit"></td><td nowrap="nowrap" width="25%"><font size="-2">&nbsp;&nbsp;<a href="advanced_search?hl=en">Advanced Search</a><br>&nbsp;&nbsp;<a href="preferences?hl=en">Preferences</a><br>&nbsp;&nbsp;<a href="language_tools?hl=en">Language Tools</a></font></td></tr></tbody></table></form><br><br><font size="-1"><a href="intl/en/ads/">Advertising&nbsp;Programs</a> - <a href="services/">Business Solutions</a> - <a href="intl/en/about.html">About Google</a></font><p><font size="-2">©2008 Google</font></p></center></body></html>
\ No newline at end of file
...@@ -4,11 +4,12 @@ ...@@ -4,11 +4,12 @@
#include "chrome/test/ui_test_utils.h" #include "chrome/test/ui_test_utils.h"
#include "base/json_reader.h"
#include "base/message_loop.h" #include "base/message_loop.h"
#include "chrome/browser/browser.h" #include "chrome/browser/browser.h"
#include "chrome/browser/dom_operation_notification_details.h" #include "chrome/browser/dom_operation_notification_details.h"
#include "chrome/browser/tab_contents/navigation_controller.h" #include "chrome/browser/tab_contents/navigation_controller.h"
#include "chrome/browser/tab_contents/web_contents.h" #include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/notification_registrar.h" #include "chrome/common/notification_registrar.h"
#include "chrome/common/notification_service.h" #include "chrome/common/notification_service.h"
#include "chrome/views/widget/accelerator_handler.h" #include "chrome/views/widget/accelerator_handler.h"
...@@ -65,6 +66,32 @@ class NavigationNotificationObserver : public NotificationObserver { ...@@ -65,6 +66,32 @@ class NavigationNotificationObserver : public NotificationObserver {
DISALLOW_COPY_AND_ASSIGN(NavigationNotificationObserver); DISALLOW_COPY_AND_ASSIGN(NavigationNotificationObserver);
}; };
class DOMOperationObserver : public NotificationObserver {
public:
explicit DOMOperationObserver(TabContents* tab_contents) {
registrar_.Add(this, NotificationType::DOM_OPERATION_RESPONSE,
Source<TabContents>(tab_contents));
RunMessageLoop();
}
virtual void Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
DCHECK(type == NotificationType::DOM_OPERATION_RESPONSE);
Details<DomOperationNotificationDetails> dom_op_details(details);
response_ = dom_op_details->json();
MessageLoopForUI::current()->Quit();
}
std::string response() const { return response_; }
private:
NotificationRegistrar registrar_;
std::string response_;
DISALLOW_COPY_AND_ASSIGN(DOMOperationObserver);
};
} // namespace } // namespace
void RunMessageLoop() { void RunMessageLoop() {
...@@ -98,42 +125,68 @@ void NavigateToURLBlockUntilNavigationsComplete(Browser* browser, ...@@ -98,42 +125,68 @@ void NavigateToURLBlockUntilNavigationsComplete(Browser* browser,
WaitForNavigations(controller, number_of_navigations); WaitForNavigations(controller, number_of_navigations);
} }
JavaScriptRunner::JavaScriptRunner(WebContents* web_contents, Value* ExecuteJavaScript(TabContents* tab_contents,
const std::wstring& frame_xpath, const std::wstring& frame_xpath,
const std::wstring& jscript) const std::wstring& original_script) {
: web_contents_(web_contents), // TODO(jcampan): we should make the domAutomationController not require an
frame_xpath_(frame_xpath), // automation id.
jscript_(jscript) { std::wstring script = L"window.domAutomationController.setAutomationId(0);" +
NotificationService::current()-> original_script;
AddObserver(this, NotificationType::DOM_OPERATION_RESPONSE, tab_contents->render_view_host()->ExecuteJavascriptInWebFrame(frame_xpath,
Source<WebContents>(web_contents)); script);
DOMOperationObserver dom_op_observer(tab_contents);
std::string json = dom_op_observer.response();
// Wrap |json| in an array before deserializing because valid JSON has an
// array or an object as the root.
json.insert(0, "[");
json.append("]");
scoped_ptr<Value> root_val(JSONReader::Read(json, true));
if (!root_val->IsType(Value::TYPE_LIST))
return NULL;
ListValue* list = static_cast<ListValue*>(root_val.get());
Value* result;
if (!list || !list->GetSize() ||
!list->Remove(0, &result)) // Remove gives us ownership of the value.
return NULL;
return result;
} }
void JavaScriptRunner::Observe(NotificationType type, bool ExecuteJavaScriptAndExtractInt(TabContents* tab_contents,
const NotificationSource& source, const std::wstring& frame_xpath,
const NotificationDetails& details) { const std::wstring& script,
Details<DomOperationNotificationDetails> dom_op_details(details); int* result) {
result_ = dom_op_details->json(); DCHECK(result);
// The Jasonified response has quotes, remove them. scoped_ptr<Value> value(ExecuteJavaScript(tab_contents, frame_xpath, script));
if (result_.length() > 1 && result_[0] == '"') if (!value.get())
result_ = result_.substr(1, result_.length() - 2); return false;
NotificationService::current()-> return value->GetAsInteger(result);
RemoveObserver(this, NotificationType::DOM_OPERATION_RESPONSE,
Source<WebContents>(web_contents_));
MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
} }
std::string JavaScriptRunner::Run() { bool ExecuteJavaScriptAndExtractBool(TabContents* tab_contents,
// The DOMAutomationController requires an automation ID, even though we are const std::wstring& frame_xpath,
// not using it in this case. const std::wstring& script,
web_contents_->render_view_host()->ExecuteJavascriptInWebFrame( bool* result) {
frame_xpath_, L"window.domAutomationController.setAutomationId(0);"); DCHECK(result);
scoped_ptr<Value> value(ExecuteJavaScript(tab_contents, frame_xpath, script));
if (!value.get())
return false;
web_contents_->render_view_host()->ExecuteJavascriptInWebFrame(frame_xpath_, return value->GetAsBoolean(result);
jscript_);
ui_test_utils::RunMessageLoop();
return result_;
} }
bool ExecuteJavaScriptAndExtractString(TabContents* tab_contents,
const std::wstring& frame_xpath,
const std::wstring& script,
std::string* result) {
DCHECK(result);
scoped_ptr<Value> value(ExecuteJavaScript(tab_contents, frame_xpath, script));
if (!value.get())
return false;
return value->GetAsString(result);
}
} // namespace ui_test_utils } // namespace ui_test_utils
...@@ -13,7 +13,8 @@ ...@@ -13,7 +13,8 @@
class Browser; class Browser;
class GURL; class GURL;
class NavigationController; class NavigationController;
class WebContents; class Value;
class TabContents;
// A collections of functions designed for use with InProcessBrowserTest. // A collections of functions designed for use with InProcessBrowserTest.
namespace ui_test_utils { namespace ui_test_utils {
...@@ -43,38 +44,32 @@ void NavigateToURLBlockUntilNavigationsComplete(Browser* browser, ...@@ -43,38 +44,32 @@ void NavigateToURLBlockUntilNavigationsComplete(Browser* browser,
int number_of_navigations); int number_of_navigations);
// This class enables you to send JavaScript as a string from the browser to the // Executes the passed |script| in the frame pointed to by |frame_xpath| (use
// renderer for execution in a frame of your choice. // empty string for main frame) and returns the value the evaluation of the
class JavaScriptRunner : public NotificationObserver { // script returned. The caller owns the returned value.
public: Value* ExecuteJavaScript(TabContents* tab_contents,
// Constructor. |web_contents| is a pointer to the WebContents you want to run const std::wstring& frame_xpath,
// the JavaScript code in. |frame_xpath| is a path to the frame to run it in. const std::wstring& script);
// |jscript| is a string containing the JavaScript code to run, for example:
// "window.domAutomationController.send(alert('hello world'));". The // The following methods executes the passed |script| in the frame pointed to by
// JavaScript code will execute when Run is called. Note: In order for the // |frame_xpath| (use empty string for main frame) and sets |result| to the
// domAutomationController to work, you must call EnableDOMAutomation() in // value returned by the script evaluation.
// your test class first. // They return true on success, false if the script evaluation failed or did not
JavaScriptRunner(WebContents* web_contents, // evaluate to the expected type.
const std::wstring& frame_xpath, // Note: In order for the domAutomationController to work, you must call
const std::wstring& jscript); // EnableDOMAutomation() in your test first.
bool ExecuteJavaScriptAndExtractInt(TabContents* tab_contents,
virtual void Observe(NotificationType type, const std::wstring& frame_xpath,
const NotificationSource& source, const std::wstring& script,
const NotificationDetails& details); int* result);
bool ExecuteJavaScriptAndExtractBool(TabContents* tab_contents,
// Executes the JavaScript code passed in to the constructor. See also comment const std::wstring& frame_xpath,
// about EnableDOMAutomation in the constructor. const std::wstring& script,
std::string Run(); bool* result);
bool ExecuteJavaScriptAndExtractString(TabContents* tab_contents,
private: const std::wstring& frame_xpath,
WebContents* web_contents_; const std::wstring& script,
std::wstring frame_xpath_; std::string* result);
std::wstring jscript_;
std::string result_;
DISALLOW_COPY_AND_ASSIGN(JavaScriptRunner);
};
} }
#endif // CHROME_TEST_UI_TEST_UTILS_H_ #endif // CHROME_TEST_UI_TEST_UTILS_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment