Roll src/third_party/skia 726cf90:183b57f
[chromium-blink-merge.git] / content / renderer / render_view_browsertest_mac.mm
blob6730da746aacfa6c84aade51397e0e32dfb65add
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/strings/string16.h"
6 #include "base/strings/string_util.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "content/public/browser/native_web_keyboard_event.h"
9 #include "content/public/common/web_preferences.h"
10 #include "content/public/test/render_view_test.h"
11 #include "content/renderer/render_view_impl.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "third_party/WebKit/public/web/WebLocalFrame.h"
15 #include <Carbon/Carbon.h>  // for the kVK_* constants.
16 #include <Cocoa/Cocoa.h>
18 namespace content {
20 NSEvent* CmdDeadKeyEvent(NSEventType type, unsigned short code) {
21   UniChar uniChar = 0;
22   switch(code) {
23     case kVK_UpArrow:
24       uniChar = NSUpArrowFunctionKey;
25       break;
26     case kVK_DownArrow:
27       uniChar = NSDownArrowFunctionKey;
28       break;
29     default:
30       CHECK(false);
31   }
32   NSString* s = [NSString stringWithFormat:@"%C", uniChar];
34   return [NSEvent keyEventWithType:type
35                           location:NSZeroPoint
36                      modifierFlags:NSCommandKeyMask
37                          timestamp:0.0
38                       windowNumber:0
39                            context:nil
40                         characters:s
41        charactersIgnoringModifiers:s
42                          isARepeat:NO
43                            keyCode:code];
46 // Test that cmd-up/down scrolls the page exactly if it is not intercepted by
47 // javascript.
48 TEST_F(RenderViewTest, MacTestCmdUp) {
49   // Some preprocessor trickery so that we can have literal html in our source,
50   // makes it easier to copy html to and from an html file for testing (the
51   // preprocessor will remove the newlines at the line ends, turning this into
52   // a single long line).
53   #define HTML(s) #s
54   const char* kRawHtml = HTML(
55   <!DOCTYPE html>
56   <style>
57     /* Add a vertical scrollbar */
58     body { height: 10128px; }
59   </style>
60   <div id='keydown'></div>
61   <div id='scroll'></div>
62   <script>
63     var allowKeyEvents = true;
64     var scroll = document.getElementById('scroll');
65     var result = document.getElementById('keydown');
66     onkeydown = function(event) {
67       result.textContent =
68         event.keyCode + ',' +
69         event.shiftKey + ',' +
70         event.ctrlKey + ',' +
71         event.metaKey + ',' +
72         event.altKey;
73       return allowKeyEvents;
74     }
75   </script>
76   <!--
77     TODO(esprehn): For some strange reason we need a non-empty document for
78     scrolling to work. This is not the case in a real browser only in the test.
79   -->
80   <p>p1
81   );
82   #undef HTML
84   WebPreferences prefs;
85   prefs.enable_scroll_animator = false;
87   RenderViewImpl* view = static_cast<RenderViewImpl*>(view_);
88   view->OnUpdateWebPreferences(prefs);
90   const int kMaxOutputCharacters = 1024;
91   base::string16 output;
93   NSEvent* arrowDownKeyDown = CmdDeadKeyEvent(NSKeyDown, kVK_DownArrow);
94   NSEvent* arrowUpKeyDown = CmdDeadKeyEvent(NSKeyDown, kVK_UpArrow);
96   // First test when javascript does not eat keypresses -- should scroll.
97   view->set_send_content_state_immediately(true);
98   LoadHTML(kRawHtml);
99   render_thread_->sink().ClearMessages();
101   const char* kArrowDownScrollDown = "40,false,false,true,false\n10144\np1";
102   view->OnSetEditCommandsForNextKeyEvent(
103       EditCommands(1, EditCommand("moveToEndOfDocument", "")));
104   SendNativeKeyEvent(NativeWebKeyboardEvent(arrowDownKeyDown));
105   ProcessPendingMessages();
106   ExecuteJavaScript("scroll.textContent = window.pageYOffset");
107   output = GetMainFrame()->contentAsText(kMaxOutputCharacters);
108   EXPECT_EQ(kArrowDownScrollDown, base::UTF16ToASCII(output));
110   const char* kArrowUpScrollUp = "38,false,false,true,false\n0\np1";
111   view->OnSetEditCommandsForNextKeyEvent(
112       EditCommands(1, EditCommand("moveToBeginningOfDocument", "")));
113   SendNativeKeyEvent(NativeWebKeyboardEvent(arrowUpKeyDown));
114   ProcessPendingMessages();
115   ExecuteJavaScript("scroll.textContent = window.pageYOffset");
116   output = GetMainFrame()->contentAsText(kMaxOutputCharacters);
117   EXPECT_EQ(kArrowUpScrollUp, base::UTF16ToASCII(output));
119   // Now let javascript eat the key events -- no scrolling should happen.
120   // Set a scroll position slightly down the page to ensure that it does not
121   // move.
122   ExecuteJavaScript("allowKeyEvents = false; window.scrollTo(0, 100)");
124   const char* kArrowDownNoScroll = "40,false,false,true,false\n100\np1";
125   view->OnSetEditCommandsForNextKeyEvent(
126       EditCommands(1, EditCommand("moveToEndOfDocument", "")));
127   SendNativeKeyEvent(NativeWebKeyboardEvent(arrowDownKeyDown));
128   ProcessPendingMessages();
129   ExecuteJavaScript("scroll.textContent = window.pageYOffset");
130   output = GetMainFrame()->contentAsText(kMaxOutputCharacters);
131   EXPECT_EQ(kArrowDownNoScroll, base::UTF16ToASCII(output));
133   const char* kArrowUpNoScroll = "38,false,false,true,false\n100\np1";
134   view->OnSetEditCommandsForNextKeyEvent(
135       EditCommands(1, EditCommand("moveToBeginningOfDocument", "")));
136   SendNativeKeyEvent(NativeWebKeyboardEvent(arrowUpKeyDown));
137   ProcessPendingMessages();
138   ExecuteJavaScript("scroll.textContent = window.pageYOffset");
139   output = GetMainFrame()->contentAsText(kMaxOutputCharacters);
140   EXPECT_EQ(kArrowUpNoScroll, base::UTF16ToASCII(output));
143 }  // namespace content