Fix infinite recursion on hiding panel when created during fullscreen mode.
[chromium-blink-merge.git] / chrome / browser / chromeos / input_method / input_method_engine_browsertests.cc
blobe71a63342d72f7ba6fcf13c6820d681cfafc41d7
1 // Copyright 2013 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 "ash/ime/input_method_menu_item.h"
6 #include "ash/ime/input_method_menu_manager.h"
7 #include "base/bind_helpers.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/extensions/extension_browsertest.h"
10 #include "chrome/browser/extensions/extension_test_message_listener.h"
11 #include "chromeos/ime/component_extension_ime_manager.h"
12 #include "chromeos/ime/composition_text.h"
13 #include "chromeos/ime/input_method_descriptor.h"
14 #include "chromeos/ime/input_method_manager.h"
15 #include "content/public/test/browser_test_utils.h"
16 #include "content/public/test/test_utils.h"
17 #include "extensions/common/manifest_handlers/background_info.h"
18 #include "ui/base/ime/chromeos/ime_bridge.h"
19 #include "ui/base/ime/chromeos/mock_ime_candidate_window_handler.h"
20 #include "ui/base/ime/chromeos/mock_ime_input_context_handler.h"
21 #include "ui/events/event.h"
23 namespace chromeos {
24 namespace input_method {
25 namespace {
27 const char kIdentityIMEID[] =
28 "_ext_ime_iafoklpfplgfnoimmaejoeondnjnlcfpIdentityIME";
29 const char kToUpperIMEID[] =
30 "_ext_ime_iafoklpfplgfnoimmaejoeondnjnlcfpToUpperIME";
31 const char kAPIArgumentIMEID[] =
32 "_ext_ime_iafoklpfplgfnoimmaejoeondnjnlcfpAPIArgumentIME";
33 const char kExtensionID[] = "iafoklpfplgfnoimmaejoeondnjnlcfp";
35 // InputMethod extension should work on 1)normal extension, 2)normal extension
36 // in incognito mode 3)component extension.
37 enum TestType {
38 kTestTypeNormal = 0,
39 kTestTypeIncognito = 1,
40 kTestTypeComponent = 2,
43 class InputMethodEngineBrowserTest
44 : public ExtensionBrowserTest,
45 public ::testing::WithParamInterface<TestType> {
46 public:
47 InputMethodEngineBrowserTest()
48 : ExtensionBrowserTest() {}
49 virtual ~InputMethodEngineBrowserTest() {}
51 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
52 ExtensionBrowserTest::SetUpInProcessBrowserTestFixture();
55 virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
56 extension_ = NULL;
59 protected:
60 void LoadTestInputMethod() {
61 // This will load "chrome/test/data/extensions/input_ime"
62 ExtensionTestMessageListener ime_ready_listener("ReadyToUseImeEvent",
63 false);
64 extension_ = LoadExtensionWithType("input_ime", GetParam());
65 ASSERT_TRUE(extension_);
66 ASSERT_TRUE(ime_ready_listener.WaitUntilSatisfied());
68 // Make sure ComponentExtensionIMEManager is initialized.
69 // ComponentExtensionIMEManagerImpl::InitializeAsync posts
70 // ReadComponentExtensionsInfo to the FILE thread for the
71 // initialization. If it is never initialized for some reasons,
72 // the test is timed out and failed.
73 ComponentExtensionIMEManager* ceimm =
74 InputMethodManager::Get()->GetComponentExtensionIMEManager();
75 while (!ceimm->IsInitialized()) {
76 content::RunAllPendingInMessageLoop(content::BrowserThread::FILE);
79 // Extension IMEs are not enabled by default.
80 std::vector<std::string> extension_ime_ids;
81 extension_ime_ids.push_back(kIdentityIMEID);
82 extension_ime_ids.push_back(kToUpperIMEID);
83 extension_ime_ids.push_back(kAPIArgumentIMEID);
84 InputMethodManager::Get()->SetEnabledExtensionImes(&extension_ime_ids);
86 InputMethodDescriptors extension_imes;
87 InputMethodManager::Get()->GetInputMethodExtensions(&extension_imes);
89 // Test IME has two input methods, thus InputMethodManager should have two
90 // extension IME.
91 // Note: Even extension is loaded by LoadExtensionAsComponent as above, the
92 // IME does not managed by ComponentExtensionIMEManager or it's id won't
93 // start with __comp__. The component extension IME is whitelisted and
94 // managed by ComponentExtensionIMEManager, but its framework is same as
95 // normal extension IME.
96 EXPECT_EQ(3U, extension_imes.size());
99 const extensions::Extension* LoadExtensionWithType(
100 const std::string& extension_name, TestType type) {
101 switch (type) {
102 case kTestTypeNormal:
103 return LoadExtension(test_data_dir_.AppendASCII(extension_name));
104 case kTestTypeIncognito:
105 return LoadExtensionIncognito(
106 test_data_dir_.AppendASCII(extension_name));
107 case kTestTypeComponent:
108 return LoadExtensionAsComponent(
109 test_data_dir_.AppendASCII(extension_name));
111 NOTREACHED();
112 return NULL;
115 const extensions::Extension* extension_;
118 class KeyEventDoneCallback {
119 public:
120 explicit KeyEventDoneCallback(bool expected_argument)
121 : expected_argument_(expected_argument),
122 is_called_(false) {}
123 ~KeyEventDoneCallback() {}
125 void Run(bool consumed) {
126 if (consumed == expected_argument_) {
127 base::MessageLoop::current()->Quit();
128 is_called_ = true;
132 void WaitUntilCalled() {
133 while (!is_called_)
134 content::RunMessageLoop();
137 private:
138 bool expected_argument_;
139 bool is_called_;
141 DISALLOW_COPY_AND_ASSIGN(KeyEventDoneCallback);
144 INSTANTIATE_TEST_CASE_P(InputMethodEngineBrowserTest,
145 InputMethodEngineBrowserTest,
146 ::testing::Values(kTestTypeNormal));
147 INSTANTIATE_TEST_CASE_P(InputMethodEngineIncognitoBrowserTest,
148 InputMethodEngineBrowserTest,
149 ::testing::Values(kTestTypeIncognito));
150 INSTANTIATE_TEST_CASE_P(InputMethodEngineComponentExtensionBrowserTest,
151 InputMethodEngineBrowserTest,
152 ::testing::Values(kTestTypeComponent));
154 IN_PROC_BROWSER_TEST_P(InputMethodEngineBrowserTest,
155 BasicScenarioTest) {
156 LoadTestInputMethod();
158 InputMethodManager::Get()->ChangeInputMethod(kIdentityIMEID);
160 scoped_ptr<MockIMEInputContextHandler> mock_input_context(
161 new MockIMEInputContextHandler());
162 scoped_ptr<MockIMECandidateWindowHandler> mock_candidate_window(
163 new MockIMECandidateWindowHandler());
165 IMEBridge::Get()->SetInputContextHandler(mock_input_context.get());
166 IMEBridge::Get()->SetCandidateWindowHandler(mock_candidate_window.get());
168 IMEEngineHandlerInterface* engine_handler =
169 IMEBridge::Get()->GetCurrentEngineHandler();
170 ASSERT_TRUE(engine_handler);
172 // onActivate event should be fired if Enable function is called.
173 ExtensionTestMessageListener activated_listener("onActivate", false);
174 engine_handler->Enable();
175 ASSERT_TRUE(activated_listener.WaitUntilSatisfied());
176 ASSERT_TRUE(activated_listener.was_satisfied());
178 // onFocus event should be fired if FocusIn function is called.
179 ExtensionTestMessageListener focus_listener("onFocus:text", false);
180 IMEEngineHandlerInterface::InputContext context(ui::TEXT_INPUT_TYPE_TEXT,
181 ui::TEXT_INPUT_MODE_DEFAULT);
182 engine_handler->FocusIn(context);
183 ASSERT_TRUE(focus_listener.WaitUntilSatisfied());
184 ASSERT_TRUE(focus_listener.was_satisfied());
186 // onKeyEvent should be fired if ProcessKeyEvent is called.
187 KeyEventDoneCallback callback(false); // EchoBackIME doesn't consume keys.
188 ExtensionTestMessageListener keyevent_listener("onKeyEvent", false);
189 ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::EF_NONE, false);
190 engine_handler->ProcessKeyEvent(key_event,
191 base::Bind(&KeyEventDoneCallback::Run,
192 base::Unretained(&callback)));
193 ASSERT_TRUE(keyevent_listener.WaitUntilSatisfied());
194 ASSERT_TRUE(keyevent_listener.was_satisfied());
195 callback.WaitUntilCalled();
197 // onSurroundingTextChange should be fired if SetSurroundingText is called.
198 ExtensionTestMessageListener surrounding_text_listener(
199 "onSurroundingTextChanged", false);
200 engine_handler->SetSurroundingText("text", // Surrounding text.
201 0, // focused position.
202 1); // anchor position.
203 ASSERT_TRUE(surrounding_text_listener.WaitUntilSatisfied());
204 ASSERT_TRUE(surrounding_text_listener.was_satisfied());
206 // onMenuItemActivated should be fired if PropertyActivate is called.
207 ExtensionTestMessageListener property_listener("onMenuItemActivated", false);
208 engine_handler->PropertyActivate("property_name");
209 ASSERT_TRUE(property_listener.WaitUntilSatisfied());
210 ASSERT_TRUE(property_listener.was_satisfied());
212 // onReset should be fired if Reset is called.
213 ExtensionTestMessageListener reset_listener("onReset", false);
214 engine_handler->Reset();
215 ASSERT_TRUE(reset_listener.WaitUntilSatisfied());
216 ASSERT_TRUE(reset_listener.was_satisfied());
218 // onBlur should be fired if FocusOut is called.
219 ExtensionTestMessageListener blur_listener("onBlur", false);
220 engine_handler->FocusOut();
221 ASSERT_TRUE(blur_listener.WaitUntilSatisfied());
222 ASSERT_TRUE(blur_listener.was_satisfied());
224 // onDeactivated should be fired if Disable is called.
225 ExtensionTestMessageListener disabled_listener("onDeactivated", false);
226 engine_handler->Disable();
227 ASSERT_TRUE(disabled_listener.WaitUntilSatisfied());
228 ASSERT_TRUE(disabled_listener.was_satisfied());
230 IMEBridge::Get()->SetInputContextHandler(NULL);
231 IMEBridge::Get()->SetCandidateWindowHandler(NULL);
234 IN_PROC_BROWSER_TEST_P(InputMethodEngineBrowserTest,
235 APIArgumentTest) {
236 LoadTestInputMethod();
238 InputMethodManager::Get()->ChangeInputMethod(kAPIArgumentIMEID);
240 scoped_ptr<MockIMEInputContextHandler> mock_input_context(
241 new MockIMEInputContextHandler());
242 scoped_ptr<MockIMECandidateWindowHandler> mock_candidate_window(
243 new MockIMECandidateWindowHandler());
245 IMEBridge::Get()->SetInputContextHandler(mock_input_context.get());
246 IMEBridge::Get()->SetCandidateWindowHandler(mock_candidate_window.get());
248 IMEEngineHandlerInterface* engine_handler =
249 IMEBridge::Get()->GetCurrentEngineHandler();
250 ASSERT_TRUE(engine_handler);
252 extensions::ExtensionHost* host = FindHostWithPath(
253 extensions::ExtensionSystem::Get(profile())->process_manager(),
254 extensions::BackgroundInfo::GetBackgroundURL(extension_).path(),
257 engine_handler->Enable();
258 IMEEngineHandlerInterface::InputContext context(ui::TEXT_INPUT_TYPE_TEXT,
259 ui::TEXT_INPUT_MODE_DEFAULT);
260 engine_handler->FocusIn(context);
263 SCOPED_TRACE("KeyDown, Ctrl:No, alt:No, Shift:No, Caps:No");
264 KeyEventDoneCallback callback(false);
265 const std::string expected_value =
266 "onKeyEvent::keydown:a:KeyA:false:false:false:false";
267 ExtensionTestMessageListener keyevent_listener(expected_value, false);
269 ui::KeyEvent key_event(
270 ui::ET_KEY_PRESSED, ui::VKEY_A, "KeyA", ui::EF_NONE, false);
271 engine_handler->ProcessKeyEvent(key_event,
272 base::Bind(&KeyEventDoneCallback::Run,
273 base::Unretained(&callback)));
274 ASSERT_TRUE(keyevent_listener.WaitUntilSatisfied());
275 EXPECT_TRUE(keyevent_listener.was_satisfied());
276 callback.WaitUntilCalled();
279 SCOPED_TRACE("KeyDown, Ctrl:Yes, alt:No, Shift:No, Caps:No");
280 KeyEventDoneCallback callback(false);
281 const std::string expected_value =
282 "onKeyEvent::keydown:a:KeyA:true:false:false:false";
283 ExtensionTestMessageListener keyevent_listener(expected_value, false);
285 ui::KeyEvent key_event(ui::ET_KEY_PRESSED,
286 ui::VKEY_A,
287 "KeyA",
288 ui::EF_CONTROL_DOWN,
289 false);
290 engine_handler->ProcessKeyEvent(key_event,
291 base::Bind(&KeyEventDoneCallback::Run,
292 base::Unretained(&callback)));
293 ASSERT_TRUE(keyevent_listener.WaitUntilSatisfied());
294 EXPECT_TRUE(keyevent_listener.was_satisfied());
295 callback.WaitUntilCalled();
298 SCOPED_TRACE("KeyDown, Ctrl:No, alt:Yes, Shift:No, Caps:No");
299 KeyEventDoneCallback callback(false);
300 const std::string expected_value =
301 "onKeyEvent::keydown:a:KeyA:false:true:false:false";
302 ExtensionTestMessageListener keyevent_listener(expected_value, false);
304 ui::KeyEvent key_event(ui::ET_KEY_PRESSED,
305 ui::VKEY_A,
306 "KeyA",
307 ui::EF_ALT_DOWN,
308 false);
309 engine_handler->ProcessKeyEvent(key_event,
310 base::Bind(&KeyEventDoneCallback::Run,
311 base::Unretained(&callback)));
312 ASSERT_TRUE(keyevent_listener.WaitUntilSatisfied());
313 EXPECT_TRUE(keyevent_listener.was_satisfied());
314 callback.WaitUntilCalled();
317 SCOPED_TRACE("KeyDown, Ctrl:No, alt:No, Shift:Yes, Caps:No");
318 KeyEventDoneCallback callback(false);
319 const std::string expected_value =
320 "onKeyEvent::keydown:A:KeyA:false:false:true:false";
321 ExtensionTestMessageListener keyevent_listener(expected_value, false);
323 ui::KeyEvent key_event(ui::ET_KEY_PRESSED,
324 ui::VKEY_A,
325 "KeyA",
326 ui::EF_SHIFT_DOWN,
327 false);
328 engine_handler->ProcessKeyEvent(key_event,
329 base::Bind(&KeyEventDoneCallback::Run,
330 base::Unretained(&callback)));
331 ASSERT_TRUE(keyevent_listener.WaitUntilSatisfied());
332 EXPECT_TRUE(keyevent_listener.was_satisfied());
333 callback.WaitUntilCalled();
336 SCOPED_TRACE("KeyDown, Ctrl:No, alt:No, Shift:No, Caps:Yes");
337 KeyEventDoneCallback callback(false);
338 const std::string expected_value =
339 "onKeyEvent::keydown:a:KeyA:false:false:false:true";
340 ExtensionTestMessageListener keyevent_listener(expected_value, false);
342 ui::KeyEvent key_event(ui::ET_KEY_PRESSED,
343 ui::VKEY_A,
344 "KeyA",
345 ui::EF_CAPS_LOCK_DOWN,
346 false);
347 engine_handler->ProcessKeyEvent(key_event,
348 base::Bind(&KeyEventDoneCallback::Run,
349 base::Unretained(&callback)));
350 ASSERT_TRUE(keyevent_listener.WaitUntilSatisfied());
351 EXPECT_TRUE(keyevent_listener.was_satisfied());
352 callback.WaitUntilCalled();
355 SCOPED_TRACE("KeyDown, Ctrl:Yes, alt:Yes, Shift:No, Caps:No");
356 KeyEventDoneCallback callback(false);
357 const std::string expected_value =
358 "onKeyEvent::keydown:a:KeyA:true:true:false:false";
359 ExtensionTestMessageListener keyevent_listener(expected_value, false);
361 ui::KeyEvent key_event(ui::ET_KEY_PRESSED,
362 ui::VKEY_A,
363 "KeyA",
364 ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN,
365 false);
366 engine_handler->ProcessKeyEvent(key_event,
367 base::Bind(&KeyEventDoneCallback::Run,
368 base::Unretained(&callback)));
369 ASSERT_TRUE(keyevent_listener.WaitUntilSatisfied());
370 EXPECT_TRUE(keyevent_listener.was_satisfied());
371 callback.WaitUntilCalled();
374 SCOPED_TRACE("KeyDown, Ctrl:No, alt:No, Shift:Yes, Caps:Yes");
375 KeyEventDoneCallback callback(false);
376 const std::string expected_value =
377 "onKeyEvent::keydown:A:KeyA:false:false:true:true";
378 ExtensionTestMessageListener keyevent_listener(expected_value, false);
380 ui::KeyEvent key_event(ui::ET_KEY_PRESSED,
381 ui::VKEY_A,
382 "KeyA",
383 ui::EF_SHIFT_DOWN | ui::EF_CAPS_LOCK_DOWN,
384 false);
385 engine_handler->ProcessKeyEvent(key_event,
386 base::Bind(&KeyEventDoneCallback::Run,
387 base::Unretained(&callback)));
388 ASSERT_TRUE(keyevent_listener.WaitUntilSatisfied());
389 EXPECT_TRUE(keyevent_listener.was_satisfied());
390 callback.WaitUntilCalled();
392 // TODO(nona): Add browser tests for other API as well.
394 SCOPED_TRACE("commitText test");
395 mock_input_context->Reset();
396 mock_candidate_window->Reset();
398 const char commit_text_test_script[] =
399 "chrome.input.ime.commitText({"
400 " contextID: engineBridge.getFocusedContextID().contextID,"
401 " text:'COMMIT_TEXT'"
402 "});";
404 ASSERT_TRUE(content::ExecuteScript(host->host_contents(),
405 commit_text_test_script));
406 EXPECT_EQ(1, mock_input_context->commit_text_call_count());
407 EXPECT_EQ("COMMIT_TEXT", mock_input_context->last_commit_text());
410 SCOPED_TRACE("sendKeyEvents test");
411 mock_input_context->Reset();
412 mock_candidate_window->Reset();
414 const char send_key_events_test_script[] =
415 "chrome.input.ime.sendKeyEvents({"
416 " contextID: engineBridge.getFocusedContextID().contextID,"
417 " keyData : [{"
418 " type : 'keydown',"
419 " requestId : '0',"
420 " key : 'z',"
421 " code : 'KeyZ',"
422 " },{"
423 " type : 'keyup',"
424 " requestId : '1',"
425 " key : 'z',"
426 " code : 'KeyZ',"
427 " }]"
428 "});";
430 ExtensionTestMessageListener keyevent_listener_down(
431 std::string("onKeyEvent:") + kExtensionID +
432 ":keydown:z:KeyZ:false:false:false:false",
433 false);
434 ExtensionTestMessageListener keyevent_listener_up(
435 std::string("onKeyEvent:") + kExtensionID +
436 ":keyup:z:KeyZ:false:false:false:false",
437 false);
439 ASSERT_TRUE(content::ExecuteScript(host->host_contents(),
440 send_key_events_test_script));
442 ASSERT_TRUE(keyevent_listener_down.WaitUntilSatisfied());
443 EXPECT_TRUE(keyevent_listener_down.was_satisfied());
444 ASSERT_TRUE(keyevent_listener_up.WaitUntilSatisfied());
445 EXPECT_TRUE(keyevent_listener_up.was_satisfied());
448 SCOPED_TRACE("setComposition test");
449 mock_input_context->Reset();
450 mock_candidate_window->Reset();
452 const char set_composition_test_script[] =
453 "chrome.input.ime.setComposition({"
454 " contextID: engineBridge.getFocusedContextID().contextID,"
455 " text:'COMPOSITION_TEXT',"
456 " cursor:4,"
457 " segments : [{"
458 " start: 0,"
459 " end: 5,"
460 " style: 'underline'"
461 " },{"
462 " start: 6,"
463 " end: 10,"
464 " style: 'doubleUnderline'"
465 " }]"
466 "});";
468 ASSERT_TRUE(content::ExecuteScript(host->host_contents(),
469 set_composition_test_script));
470 EXPECT_EQ(1, mock_input_context->update_preedit_text_call_count());
472 EXPECT_EQ(4U,
473 mock_input_context->last_update_composition_arg().cursor_pos);
474 EXPECT_TRUE(mock_input_context->last_update_composition_arg().is_visible);
476 const CompositionText& composition_text =
477 mock_input_context->last_update_composition_arg().composition_text;
478 EXPECT_EQ(base::UTF8ToUTF16("COMPOSITION_TEXT"), composition_text.text());
479 const std::vector<CompositionText::UnderlineAttribute>& underlines =
480 composition_text.underline_attributes();
482 ASSERT_EQ(2U, underlines.size());
483 EXPECT_EQ(CompositionText::COMPOSITION_TEXT_UNDERLINE_SINGLE,
484 underlines[0].type);
485 EXPECT_EQ(0U, underlines[0].start_index);
486 EXPECT_EQ(5U, underlines[0].end_index);
488 EXPECT_EQ(CompositionText::COMPOSITION_TEXT_UNDERLINE_DOUBLE,
489 underlines[1].type);
490 EXPECT_EQ(6U, underlines[1].start_index);
491 EXPECT_EQ(10U, underlines[1].end_index);
494 SCOPED_TRACE("clearComposition test");
495 mock_input_context->Reset();
496 mock_candidate_window->Reset();
498 const char commite_text_test_script[] =
499 "chrome.input.ime.clearComposition({"
500 " contextID: engineBridge.getFocusedContextID().contextID,"
501 "});";
503 ASSERT_TRUE(content::ExecuteScript(host->host_contents(),
504 commite_text_test_script));
505 EXPECT_EQ(1, mock_input_context->update_preedit_text_call_count());
506 EXPECT_FALSE(
507 mock_input_context->last_update_composition_arg().is_visible);
508 const CompositionText& composition_text =
509 mock_input_context->last_update_composition_arg().composition_text;
510 EXPECT_TRUE(composition_text.text().empty());
513 SCOPED_TRACE("setCandidateWindowProperties:visibility test");
514 mock_input_context->Reset();
515 mock_candidate_window->Reset();
517 const char set_candidate_window_properties_test_script[] =
518 "chrome.input.ime.setCandidateWindowProperties({"
519 " engineID: engineBridge.getActiveEngineID(),"
520 " properties: {"
521 " visible: true,"
522 " }"
523 "});";
524 ASSERT_TRUE(content::ExecuteScript(
525 host->host_contents(),
526 set_candidate_window_properties_test_script));
527 EXPECT_EQ(1, mock_candidate_window->update_lookup_table_call_count());
528 EXPECT_TRUE(
529 mock_candidate_window->last_update_lookup_table_arg().is_visible);
532 SCOPED_TRACE("setCandidateWindowProperties:cursor_visibility test");
533 mock_input_context->Reset();
534 mock_candidate_window->Reset();
536 const char set_candidate_window_properties_test_script[] =
537 "chrome.input.ime.setCandidateWindowProperties({"
538 " engineID: engineBridge.getActiveEngineID(),"
539 " properties: {"
540 " cursorVisible: true,"
541 " }"
542 "});";
543 ASSERT_TRUE(content::ExecuteScript(
544 host->host_contents(),
545 set_candidate_window_properties_test_script));
546 EXPECT_EQ(1, mock_candidate_window->update_lookup_table_call_count());
548 // window visibility is kept as before.
549 EXPECT_TRUE(
550 mock_candidate_window->last_update_lookup_table_arg().is_visible);
552 const ui::CandidateWindow& table =
553 mock_candidate_window->last_update_lookup_table_arg().lookup_table;
554 EXPECT_TRUE(table.is_cursor_visible());
557 SCOPED_TRACE("setCandidateWindowProperties:vertical test");
558 mock_input_context->Reset();
559 mock_candidate_window->Reset();
561 const char set_candidate_window_properties_test_script[] =
562 "chrome.input.ime.setCandidateWindowProperties({"
563 " engineID: engineBridge.getActiveEngineID(),"
564 " properties: {"
565 " vertical: true,"
566 " }"
567 "});";
568 ASSERT_TRUE(content::ExecuteScript(
569 host->host_contents(),
570 set_candidate_window_properties_test_script));
571 EXPECT_EQ(1, mock_candidate_window->update_lookup_table_call_count());
573 // window visibility is kept as before.
574 EXPECT_TRUE(
575 mock_candidate_window->last_update_lookup_table_arg().is_visible);
577 const ui::CandidateWindow& table =
578 mock_candidate_window->last_update_lookup_table_arg().lookup_table;
580 // cursor visibility is kept as before.
581 EXPECT_TRUE(table.is_cursor_visible());
583 EXPECT_EQ(ui::CandidateWindow::VERTICAL, table.orientation());
586 SCOPED_TRACE("setCandidateWindowProperties:pageSize test");
587 mock_input_context->Reset();
588 mock_candidate_window->Reset();
590 const char set_candidate_window_properties_test_script[] =
591 "chrome.input.ime.setCandidateWindowProperties({"
592 " engineID: engineBridge.getActiveEngineID(),"
593 " properties: {"
594 " pageSize: 7,"
595 " }"
596 "});";
597 ASSERT_TRUE(content::ExecuteScript(
598 host->host_contents(),
599 set_candidate_window_properties_test_script));
600 EXPECT_EQ(1, mock_candidate_window->update_lookup_table_call_count());
602 // window visibility is kept as before.
603 EXPECT_TRUE(
604 mock_candidate_window->last_update_lookup_table_arg().is_visible);
606 const ui::CandidateWindow& table =
607 mock_candidate_window->last_update_lookup_table_arg().lookup_table;
609 // cursor visibility is kept as before.
610 EXPECT_TRUE(table.is_cursor_visible());
612 // oritantation is kept as before.
613 EXPECT_EQ(ui::CandidateWindow::VERTICAL, table.orientation());
615 EXPECT_EQ(7U, table.page_size());
618 SCOPED_TRACE("setCandidateWindowProperties:auxTextVisibility test");
619 mock_input_context->Reset();
620 mock_candidate_window->Reset();
622 const char set_candidate_window_properties_test_script[] =
623 "chrome.input.ime.setCandidateWindowProperties({"
624 " engineID: engineBridge.getActiveEngineID(),"
625 " properties: {"
626 " auxiliaryTextVisible: true"
627 " }"
628 "});";
629 ASSERT_TRUE(content::ExecuteScript(
630 host->host_contents(),
631 set_candidate_window_properties_test_script));
632 EXPECT_EQ(1, mock_candidate_window->update_lookup_table_call_count());
634 const ui::CandidateWindow& table =
635 mock_candidate_window->last_update_lookup_table_arg().lookup_table;
636 EXPECT_TRUE(table.is_auxiliary_text_visible());
639 SCOPED_TRACE("setCandidateWindowProperties:auxText test");
640 mock_input_context->Reset();
641 mock_candidate_window->Reset();
643 const char set_candidate_window_properties_test_script[] =
644 "chrome.input.ime.setCandidateWindowProperties({"
645 " engineID: engineBridge.getActiveEngineID(),"
646 " properties: {"
647 " auxiliaryText: 'AUXILIARY_TEXT'"
648 " }"
649 "});";
650 ASSERT_TRUE(content::ExecuteScript(
651 host->host_contents(),
652 set_candidate_window_properties_test_script));
653 EXPECT_EQ(1, mock_candidate_window->update_lookup_table_call_count());
655 // aux text visibility is kept as before.
656 const ui::CandidateWindow& table =
657 mock_candidate_window->last_update_lookup_table_arg().lookup_table;
658 EXPECT_TRUE(table.is_auxiliary_text_visible());
659 EXPECT_EQ("AUXILIARY_TEXT", table.auxiliary_text());
662 SCOPED_TRACE("setCandidates test");
663 mock_input_context->Reset();
664 mock_candidate_window->Reset();
666 const char set_candidates_test_script[] =
667 "chrome.input.ime.setCandidates({"
668 " contextID: engineBridge.getFocusedContextID().contextID,"
669 " candidates: [{"
670 " candidate: 'CANDIDATE_1',"
671 " id: 1,"
672 " },{"
673 " candidate: 'CANDIDATE_2',"
674 " id: 2,"
675 " label: 'LABEL_2',"
676 " },{"
677 " candidate: 'CANDIDATE_3',"
678 " id: 3,"
679 " label: 'LABEL_3',"
680 " annotation: 'ANNOTACTION_3'"
681 " },{"
682 " candidate: 'CANDIDATE_4',"
683 " id: 4,"
684 " label: 'LABEL_4',"
685 " annotation: 'ANNOTACTION_4',"
686 " usage: {"
687 " title: 'TITLE_4',"
688 " body: 'BODY_4'"
689 " }"
690 " }]"
691 "});";
692 ASSERT_TRUE(content::ExecuteScript(host->host_contents(),
693 set_candidates_test_script));
695 // window visibility is kept as before.
696 EXPECT_TRUE(
697 mock_candidate_window->last_update_lookup_table_arg().is_visible);
699 const ui::CandidateWindow& table =
700 mock_candidate_window->last_update_lookup_table_arg().lookup_table;
702 // cursor visibility is kept as before.
703 EXPECT_TRUE(table.is_cursor_visible());
705 // oritantation is kept as before.
706 EXPECT_EQ(ui::CandidateWindow::VERTICAL, table.orientation());
708 // page size is kept as before.
709 EXPECT_EQ(7U, table.page_size());
711 ASSERT_EQ(4U, table.candidates().size());
713 EXPECT_EQ(base::UTF8ToUTF16("CANDIDATE_1"),
714 table.candidates().at(0).value);
716 EXPECT_EQ(base::UTF8ToUTF16("CANDIDATE_2"),
717 table.candidates().at(1).value);
718 EXPECT_EQ(base::UTF8ToUTF16("LABEL_2"), table.candidates().at(1).label);
720 EXPECT_EQ(base::UTF8ToUTF16("CANDIDATE_3"),
721 table.candidates().at(2).value);
722 EXPECT_EQ(base::UTF8ToUTF16("LABEL_3"), table.candidates().at(2).label);
723 EXPECT_EQ(base::UTF8ToUTF16("ANNOTACTION_3"),
724 table.candidates().at(2).annotation);
726 EXPECT_EQ(base::UTF8ToUTF16("CANDIDATE_4"),
727 table.candidates().at(3).value);
728 EXPECT_EQ(base::UTF8ToUTF16("LABEL_4"), table.candidates().at(3).label);
729 EXPECT_EQ(base::UTF8ToUTF16("ANNOTACTION_4"),
730 table.candidates().at(3).annotation);
731 EXPECT_EQ(base::UTF8ToUTF16("TITLE_4"),
732 table.candidates().at(3).description_title);
733 EXPECT_EQ(base::UTF8ToUTF16("BODY_4"),
734 table.candidates().at(3).description_body);
737 SCOPED_TRACE("setCursorPosition test");
738 mock_input_context->Reset();
739 mock_candidate_window->Reset();
741 const char set_cursor_position_test_script[] =
742 "chrome.input.ime.setCursorPosition({"
743 " contextID: engineBridge.getFocusedContextID().contextID,"
744 " candidateID: 2"
745 "});";
746 ASSERT_TRUE(content::ExecuteScript(
747 host->host_contents(), set_cursor_position_test_script));
748 EXPECT_EQ(1, mock_candidate_window->update_lookup_table_call_count());
750 // window visibility is kept as before.
751 EXPECT_TRUE(
752 mock_candidate_window->last_update_lookup_table_arg().is_visible);
754 const ui::CandidateWindow& table =
755 mock_candidate_window->last_update_lookup_table_arg().lookup_table;
757 // cursor visibility is kept as before.
758 EXPECT_TRUE(table.is_cursor_visible());
760 // oritantation is kept as before.
761 EXPECT_EQ(ui::CandidateWindow::VERTICAL, table.orientation());
763 // page size is kept as before.
764 EXPECT_EQ(7U, table.page_size());
766 // candidates are same as before.
767 ASSERT_EQ(4U, table.candidates().size());
769 // Candidate ID == 2 is 1 in index.
770 EXPECT_EQ(1U, table.cursor_position());
773 SCOPED_TRACE("setMenuItem test");
774 mock_input_context->Reset();
775 mock_candidate_window->Reset();
777 const char set_menu_item_test_script[] =
778 "chrome.input.ime.setMenuItems({"
779 " engineID: engineBridge.getActiveEngineID(),"
780 " items: [{"
781 " id: 'ID0',"
782 " },{"
783 " id: 'ID1',"
784 " label: 'LABEL1',"
785 " },{"
786 " id: 'ID2',"
787 " label: 'LABEL2',"
788 " style: 'radio',"
789 " },{"
790 " id: 'ID3',"
791 " label: 'LABEL3',"
792 " style: 'check',"
793 " visible: true,"
794 " },{"
795 " id: 'ID4',"
796 " label: 'LABEL4',"
797 " style: 'separator',"
798 " visible: true,"
799 " checked: true"
800 " }]"
801 "});";
802 ASSERT_TRUE(content::ExecuteScript(
803 host->host_contents(), set_menu_item_test_script));
805 const ash::ime::InputMethodMenuItemList& props =
806 ash::ime::InputMethodMenuManager::GetInstance()->
807 GetCurrentInputMethodMenuItemList();
808 ASSERT_EQ(5U, props.size());
810 EXPECT_EQ("ID0", props[0].key);
811 EXPECT_EQ("ID1", props[1].key);
812 EXPECT_EQ("ID2", props[2].key);
813 EXPECT_EQ("ID3", props[3].key);
814 EXPECT_EQ("ID4", props[4].key);
816 EXPECT_EQ("LABEL1", props[1].label);
817 EXPECT_EQ("LABEL2", props[2].label);
818 EXPECT_EQ("LABEL3", props[3].label);
819 EXPECT_EQ("LABEL4", props[4].label);
821 EXPECT_TRUE(props[2].is_selection_item);
822 // TODO(nona): Add tests for style: ["toggle" and "separator"]
823 // and visible:, when implement them.
825 EXPECT_TRUE(props[4].is_selection_item_checked);
828 SCOPED_TRACE("deleteSurroundingText test");
829 mock_input_context->Reset();
830 mock_candidate_window->Reset();
832 const char delete_surrounding_text_test_script[] =
833 "chrome.input.ime.deleteSurroundingText({"
834 " engineID: engineBridge.getActiveEngineID(),"
835 " contextID: engineBridge.getFocusedContextID().contextID,"
836 " offset: 5,"
837 " length: 3"
838 "});";
839 ASSERT_TRUE(content::ExecuteScript(
840 host->host_contents(), delete_surrounding_text_test_script));
842 EXPECT_EQ(1, mock_input_context->delete_surrounding_text_call_count());
843 EXPECT_EQ(5, mock_input_context->last_delete_surrounding_text_arg().offset);
844 EXPECT_EQ(3U,
845 mock_input_context->last_delete_surrounding_text_arg().length);
848 SCOPED_TRACE("onFocus test");
849 mock_input_context->Reset();
850 mock_candidate_window->Reset();
853 ExtensionTestMessageListener focus_listener("onFocus:text", false);
854 IMEEngineHandlerInterface::InputContext context(
855 ui::TEXT_INPUT_TYPE_TEXT, ui::TEXT_INPUT_MODE_DEFAULT);
856 engine_handler->FocusIn(context);
857 ASSERT_TRUE(focus_listener.WaitUntilSatisfied());
858 ASSERT_TRUE(focus_listener.was_satisfied());
861 ExtensionTestMessageListener focus_listener("onFocus:search", false);
862 IMEEngineHandlerInterface::InputContext context(
863 ui::TEXT_INPUT_TYPE_SEARCH, ui::TEXT_INPUT_MODE_DEFAULT);
864 engine_handler->FocusIn(context);
865 ASSERT_TRUE(focus_listener.WaitUntilSatisfied());
866 ASSERT_TRUE(focus_listener.was_satisfied());
869 ExtensionTestMessageListener focus_listener("onFocus:tel", false);
870 IMEEngineHandlerInterface::InputContext context(
871 ui::TEXT_INPUT_TYPE_TELEPHONE, ui::TEXT_INPUT_MODE_DEFAULT);
872 engine_handler->FocusIn(context);
873 ASSERT_TRUE(focus_listener.WaitUntilSatisfied());
874 ASSERT_TRUE(focus_listener.was_satisfied());
877 ExtensionTestMessageListener focus_listener("onFocus:url", false);
878 IMEEngineHandlerInterface::InputContext context(
879 ui::TEXT_INPUT_TYPE_URL, ui::TEXT_INPUT_MODE_DEFAULT);
880 engine_handler->FocusIn(context);
881 ASSERT_TRUE(focus_listener.WaitUntilSatisfied());
882 ASSERT_TRUE(focus_listener.was_satisfied());
885 ExtensionTestMessageListener focus_listener("onFocus:email", false);
886 IMEEngineHandlerInterface::InputContext context(
887 ui::TEXT_INPUT_TYPE_EMAIL, ui::TEXT_INPUT_MODE_DEFAULT);
888 engine_handler->FocusIn(context);
889 ASSERT_TRUE(focus_listener.WaitUntilSatisfied());
890 ASSERT_TRUE(focus_listener.was_satisfied());
893 ExtensionTestMessageListener focus_listener("onFocus:number", false);
894 IMEEngineHandlerInterface::InputContext context(
895 ui::TEXT_INPUT_TYPE_NUMBER, ui::TEXT_INPUT_MODE_DEFAULT);
896 engine_handler->FocusIn(context);
897 ASSERT_TRUE(focus_listener.WaitUntilSatisfied());
898 ASSERT_TRUE(focus_listener.was_satisfied());
902 IMEBridge::Get()->SetInputContextHandler(NULL);
903 IMEBridge::Get()->SetCandidateWindowHandler(NULL);
906 } // namespace
907 } // namespace input_method
908 } // namespace chromeos