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