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