Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / chromeos / input_method / input_method_engine_browsertests.cc
blobc8d3aea35586f653f3e3b943e9f9540cb086934e
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 "base/bind_helpers.h"
6 #include "chrome/browser/extensions/extension_browsertest.h"
7 #include "chrome/browser/extensions/extension_test_message_listener.h"
8 #include "chromeos/ime/component_extension_ime_manager.h"
9 #include "chromeos/ime/ibus_text.h"
10 #include "chromeos/ime/input_method_descriptor.h"
11 #include "chromeos/ime/input_method_manager.h"
12 #include "content/public/test/browser_test_utils.h"
13 #include "content/public/test/test_utils.h"
14 #include "extensions/common/manifest_handlers/background_info.h"
15 #include "ui/base/ime/chromeos/ibus_bridge.h"
16 #include "ui/base/ime/chromeos/mock_ime_candidate_window_handler.h"
17 #include "ui/base/ime/chromeos/mock_ime_input_context_handler.h"
18 #include "ui/events/event.h"
20 namespace chromeos {
21 namespace input_method {
22 namespace {
24 const char kIdentityIMEID[] =
25 "_ext_ime_iafoklpfplgfnoimmaejoeondnjnlcfpIdentityIME";
26 const char kToUpperIMEID[] =
27 "_ext_ime_iafoklpfplgfnoimmaejoeondnjnlcfpToUpperIME";
28 const char kAPIArgumentIMEID[] =
29 "_ext_ime_iafoklpfplgfnoimmaejoeondnjnlcfpAPIArgumentIME";
31 // InputMethod extension should work on 1)normal extension, 2)normal extension
32 // in incognito mode 3)component extension.
33 enum TestType {
34 kTestTypeNormal = 0,
35 kTestTypeIncognito = 1,
36 kTestTypeComponent = 2,
39 class InputMethodEngineIBusBrowserTest
40 : public ExtensionBrowserTest,
41 public ::testing::WithParamInterface<TestType> {
42 public:
43 InputMethodEngineIBusBrowserTest()
44 : ExtensionBrowserTest() {}
45 virtual ~InputMethodEngineIBusBrowserTest() {}
47 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
48 ExtensionBrowserTest::SetUpInProcessBrowserTestFixture();
51 virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
52 extension_ = NULL;
55 protected:
56 void LoadTestInputMethod() {
57 // This will load "chrome/test/data/extensions/input_ime"
58 ExtensionTestMessageListener ime_ready_listener("ReadyToUseImeEvent",
59 false);
60 extension_ = LoadExtensionWithType("input_ime", GetParam());
61 ASSERT_TRUE(extension_);
62 ASSERT_TRUE(ime_ready_listener.WaitUntilSatisfied());
64 // Make sure ComponentExtensionIMEManager is initialized.
65 // ComponentExtensionIMEManagerImpl::InitializeAsync posts
66 // ReadComponentExtensionsInfo to the FILE thread for the
67 // initialization. If it is never initialized for some reasons,
68 // the test is timed out and failed.
69 ComponentExtensionIMEManager* ceimm =
70 InputMethodManager::Get()->GetComponentExtensionIMEManager();
71 while (!ceimm->IsInitialized()) {
72 content::RunAllPendingInMessageLoop(content::BrowserThread::FILE);
75 // Extension IMEs are not enabled by default.
76 std::vector<std::string> extension_ime_ids;
77 extension_ime_ids.push_back(kIdentityIMEID);
78 extension_ime_ids.push_back(kToUpperIMEID);
79 extension_ime_ids.push_back(kAPIArgumentIMEID);
80 InputMethodManager::Get()->SetEnabledExtensionImes(&extension_ime_ids);
82 InputMethodDescriptors extension_imes;
83 InputMethodManager::Get()->GetInputMethodExtensions(&extension_imes);
85 // Test IME has two input methods, thus InputMethodManager should have two
86 // extension IME.
87 // Note: Even extension is loaded by LoadExtensionAsComponent as above, the
88 // IME does not managed by ComponentExtensionIMEManager or it's id won't
89 // start with __comp__. The component extension IME is whitelisted and
90 // managed by ComponentExtensionIMEManager, but its framework is same as
91 // normal extension IME.
92 EXPECT_EQ(3U, extension_imes.size());
95 const extensions::Extension* LoadExtensionWithType(
96 const std::string& extension_name, TestType type) {
97 switch (type) {
98 case kTestTypeNormal:
99 return LoadExtension(test_data_dir_.AppendASCII(extension_name));
100 case kTestTypeIncognito:
101 return LoadExtensionIncognito(
102 test_data_dir_.AppendASCII(extension_name));
103 case kTestTypeComponent:
104 return LoadExtensionAsComponent(
105 test_data_dir_.AppendASCII(extension_name));
107 NOTREACHED();
108 return NULL;
111 const extensions::Extension* extension_;
114 class KeyEventDoneCallback {
115 public:
116 explicit KeyEventDoneCallback(bool expected_argument)
117 : expected_argument_(expected_argument),
118 is_called_(false) {}
119 ~KeyEventDoneCallback() {}
121 void Run(bool consumed) {
122 if (consumed == expected_argument_) {
123 base::MessageLoop::current()->Quit();
124 is_called_ = true;
128 void WaitUntilCalled() {
129 while (!is_called_)
130 content::RunMessageLoop();
133 private:
134 bool expected_argument_;
135 bool is_called_;
137 DISALLOW_COPY_AND_ASSIGN(KeyEventDoneCallback);
140 INSTANTIATE_TEST_CASE_P(InputMethodEngineIBusBrowserTest,
141 InputMethodEngineIBusBrowserTest,
142 ::testing::Values(kTestTypeNormal));
143 INSTANTIATE_TEST_CASE_P(InputMethodEngineIBusIncognitoBrowserTest,
144 InputMethodEngineIBusBrowserTest,
145 ::testing::Values(kTestTypeIncognito));
146 INSTANTIATE_TEST_CASE_P(InputMethodEngineIBusComponentExtensionBrowserTest,
147 InputMethodEngineIBusBrowserTest,
148 ::testing::Values(kTestTypeComponent));
150 IN_PROC_BROWSER_TEST_P(InputMethodEngineIBusBrowserTest,
151 BasicScenarioTest) {
152 LoadTestInputMethod();
154 InputMethodManager::Get()->ChangeInputMethod(kIdentityIMEID);
156 scoped_ptr<MockIMEInputContextHandler> mock_input_context(
157 new MockIMEInputContextHandler());
158 scoped_ptr<MockIMECandidateWindowHandler> mock_candidate_window(
159 new MockIMECandidateWindowHandler());
161 IBusBridge::Get()->SetInputContextHandler(mock_input_context.get());
162 IBusBridge::Get()->SetCandidateWindowHandler(mock_candidate_window.get());
164 IBusEngineHandlerInterface* engine_handler =
165 IBusBridge::Get()->GetCurrentEngineHandler();
166 ASSERT_TRUE(engine_handler);
168 // onActivate event should be fired if Enable function is called.
169 ExtensionTestMessageListener activated_listener("onActivate", false);
170 engine_handler->Enable();
171 ASSERT_TRUE(activated_listener.WaitUntilSatisfied());
172 ASSERT_TRUE(activated_listener.was_satisfied());
174 // onFocus event should be fired if FocusIn function is called.
175 ExtensionTestMessageListener focus_listener("onFocus:text", false);
176 IBusEngineHandlerInterface::InputContext context(ui::TEXT_INPUT_TYPE_TEXT,
177 ui::TEXT_INPUT_MODE_DEFAULT);
178 engine_handler->FocusIn(context);
179 ASSERT_TRUE(focus_listener.WaitUntilSatisfied());
180 ASSERT_TRUE(focus_listener.was_satisfied());
182 // onKeyEvent should be fired if ProcessKeyEvent is called.
183 KeyEventDoneCallback callback(false); // EchoBackIME doesn't consume keys.
184 ExtensionTestMessageListener keyevent_listener("onKeyEvent", false);
185 ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::EF_NONE, false);
186 engine_handler->ProcessKeyEvent(key_event,
187 base::Bind(&KeyEventDoneCallback::Run,
188 base::Unretained(&callback)));
189 ASSERT_TRUE(keyevent_listener.WaitUntilSatisfied());
190 ASSERT_TRUE(keyevent_listener.was_satisfied());
191 callback.WaitUntilCalled();
193 // onSurroundingTextChange should be fired if SetSurroundingText is called.
194 ExtensionTestMessageListener surrounding_text_listener(
195 "onSurroundingTextChanged", false);
196 engine_handler->SetSurroundingText("text", // Surrounding text.
197 0, // focused position.
198 1); // anchor position.
199 ASSERT_TRUE(surrounding_text_listener.WaitUntilSatisfied());
200 ASSERT_TRUE(surrounding_text_listener.was_satisfied());
202 // onMenuItemActivated should be fired if PropertyActivate is called.
203 ExtensionTestMessageListener property_listener("onMenuItemActivated", false);
204 engine_handler->PropertyActivate("property_name");
205 ASSERT_TRUE(property_listener.WaitUntilSatisfied());
206 ASSERT_TRUE(property_listener.was_satisfied());
208 // onReset should be fired if Reset is called.
209 ExtensionTestMessageListener reset_listener("onReset", false);
210 engine_handler->Reset();
211 ASSERT_TRUE(reset_listener.WaitUntilSatisfied());
212 ASSERT_TRUE(reset_listener.was_satisfied());
214 // onBlur should be fired if FocusOut is called.
215 ExtensionTestMessageListener blur_listener("onBlur", false);
216 engine_handler->FocusOut();
217 ASSERT_TRUE(blur_listener.WaitUntilSatisfied());
218 ASSERT_TRUE(blur_listener.was_satisfied());
220 // onDeactivated should be fired if Disable is called.
221 ExtensionTestMessageListener disabled_listener("onDeactivated", false);
222 engine_handler->Disable();
223 ASSERT_TRUE(disabled_listener.WaitUntilSatisfied());
224 ASSERT_TRUE(disabled_listener.was_satisfied());
226 IBusBridge::Get()->SetInputContextHandler(NULL);
227 IBusBridge::Get()->SetCandidateWindowHandler(NULL);
230 IN_PROC_BROWSER_TEST_P(InputMethodEngineIBusBrowserTest,
231 APIArgumentTest) {
232 LoadTestInputMethod();
234 InputMethodManager::Get()->ChangeInputMethod(kAPIArgumentIMEID);
236 scoped_ptr<MockIMEInputContextHandler> mock_input_context(
237 new MockIMEInputContextHandler());
238 scoped_ptr<MockIMECandidateWindowHandler> mock_candidate_window(
239 new MockIMECandidateWindowHandler());
241 IBusBridge::Get()->SetInputContextHandler(mock_input_context.get());
242 IBusBridge::Get()->SetCandidateWindowHandler(mock_candidate_window.get());
244 IBusEngineHandlerInterface* engine_handler =
245 IBusBridge::Get()->GetCurrentEngineHandler();
246 ASSERT_TRUE(engine_handler);
248 extensions::ExtensionHost* host = FindHostWithPath(
249 extensions::ExtensionSystem::Get(profile())->process_manager(),
250 extensions::BackgroundInfo::GetBackgroundURL(extension_).path(),
253 engine_handler->Enable();
254 IBusEngineHandlerInterface::InputContext context(ui::TEXT_INPUT_TYPE_TEXT,
255 ui::TEXT_INPUT_MODE_DEFAULT);
256 engine_handler->FocusIn(context);
259 SCOPED_TRACE("KeyDown, Ctrl:No, alt:No, Shift:No, Caps:No");
260 KeyEventDoneCallback callback(false);
261 const std::string expected_value =
262 "onKeyEvent:keydown:a:KeyA:false:false:false:false";
263 ExtensionTestMessageListener keyevent_listener(expected_value, false);
265 ui::KeyEvent key_event(
266 ui::ET_KEY_PRESSED, ui::VKEY_A, "KeyA", ui::EF_NONE, false);
267 engine_handler->ProcessKeyEvent(key_event,
268 base::Bind(&KeyEventDoneCallback::Run,
269 base::Unretained(&callback)));
270 ASSERT_TRUE(keyevent_listener.WaitUntilSatisfied());
271 EXPECT_TRUE(keyevent_listener.was_satisfied());
272 callback.WaitUntilCalled();
275 SCOPED_TRACE("KeyDown, Ctrl:Yes, alt:No, Shift:No, Caps:No");
276 KeyEventDoneCallback callback(false);
277 const std::string expected_value =
278 "onKeyEvent:keydown:a:KeyA:true:false:false:false";
279 ExtensionTestMessageListener keyevent_listener(expected_value, false);
281 ui::KeyEvent key_event(ui::ET_KEY_PRESSED,
282 ui::VKEY_A,
283 "KeyA",
284 ui::EF_CONTROL_DOWN,
285 false);
286 engine_handler->ProcessKeyEvent(key_event,
287 base::Bind(&KeyEventDoneCallback::Run,
288 base::Unretained(&callback)));
289 ASSERT_TRUE(keyevent_listener.WaitUntilSatisfied());
290 EXPECT_TRUE(keyevent_listener.was_satisfied());
291 callback.WaitUntilCalled();
294 SCOPED_TRACE("KeyDown, Ctrl:No, alt:Yes, Shift:No, Caps:No");
295 KeyEventDoneCallback callback(false);
296 const std::string expected_value =
297 "onKeyEvent:keydown:a:KeyA:false:true:false:false";
298 ExtensionTestMessageListener keyevent_listener(expected_value, false);
300 ui::KeyEvent key_event(ui::ET_KEY_PRESSED,
301 ui::VKEY_A,
302 "KeyA",
303 ui::EF_ALT_DOWN,
304 false);
305 engine_handler->ProcessKeyEvent(key_event,
306 base::Bind(&KeyEventDoneCallback::Run,
307 base::Unretained(&callback)));
308 ASSERT_TRUE(keyevent_listener.WaitUntilSatisfied());
309 EXPECT_TRUE(keyevent_listener.was_satisfied());
310 callback.WaitUntilCalled();
313 SCOPED_TRACE("KeyDown, Ctrl:No, alt:No, Shift:Yes, Caps:No");
314 KeyEventDoneCallback callback(false);
315 const std::string expected_value =
316 "onKeyEvent:keydown:A:KeyA:false:false:true:false";
317 ExtensionTestMessageListener keyevent_listener(expected_value, false);
319 ui::KeyEvent key_event(ui::ET_KEY_PRESSED,
320 ui::VKEY_A,
321 "KeyA",
322 ui::EF_SHIFT_DOWN,
323 false);
324 engine_handler->ProcessKeyEvent(key_event,
325 base::Bind(&KeyEventDoneCallback::Run,
326 base::Unretained(&callback)));
327 ASSERT_TRUE(keyevent_listener.WaitUntilSatisfied());
328 EXPECT_TRUE(keyevent_listener.was_satisfied());
329 callback.WaitUntilCalled();
332 SCOPED_TRACE("KeyDown, Ctrl:No, alt:No, Shift:No, Caps:Yes");
333 KeyEventDoneCallback callback(false);
334 const std::string expected_value =
335 "onKeyEvent:keydown:a:KeyA:false:false:false:true";
336 ExtensionTestMessageListener keyevent_listener(expected_value, false);
338 ui::KeyEvent key_event(ui::ET_KEY_PRESSED,
339 ui::VKEY_A,
340 "KeyA",
341 ui::EF_CAPS_LOCK_DOWN,
342 false);
343 engine_handler->ProcessKeyEvent(key_event,
344 base::Bind(&KeyEventDoneCallback::Run,
345 base::Unretained(&callback)));
346 ASSERT_TRUE(keyevent_listener.WaitUntilSatisfied());
347 EXPECT_TRUE(keyevent_listener.was_satisfied());
348 callback.WaitUntilCalled();
351 SCOPED_TRACE("KeyDown, Ctrl:Yes, alt:Yes, Shift:No, Caps:No");
352 KeyEventDoneCallback callback(false);
353 const std::string expected_value =
354 "onKeyEvent:keydown:a:KeyA:true:true:false:false";
355 ExtensionTestMessageListener keyevent_listener(expected_value, false);
357 ui::KeyEvent key_event(ui::ET_KEY_PRESSED,
358 ui::VKEY_A,
359 "KeyA",
360 ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN,
361 false);
362 engine_handler->ProcessKeyEvent(key_event,
363 base::Bind(&KeyEventDoneCallback::Run,
364 base::Unretained(&callback)));
365 ASSERT_TRUE(keyevent_listener.WaitUntilSatisfied());
366 EXPECT_TRUE(keyevent_listener.was_satisfied());
367 callback.WaitUntilCalled();
370 SCOPED_TRACE("KeyDown, Ctrl:No, alt:No, Shift:Yes, Caps:Yes");
371 KeyEventDoneCallback callback(false);
372 const std::string expected_value =
373 "onKeyEvent:keydown:A:KeyA:false:false:true:true";
374 ExtensionTestMessageListener keyevent_listener(expected_value, false);
376 ui::KeyEvent key_event(ui::ET_KEY_PRESSED,
377 ui::VKEY_A,
378 "KeyA",
379 ui::EF_SHIFT_DOWN | ui::EF_CAPS_LOCK_DOWN,
380 false);
381 engine_handler->ProcessKeyEvent(key_event,
382 base::Bind(&KeyEventDoneCallback::Run,
383 base::Unretained(&callback)));
384 ASSERT_TRUE(keyevent_listener.WaitUntilSatisfied());
385 EXPECT_TRUE(keyevent_listener.was_satisfied());
386 callback.WaitUntilCalled();
388 // TODO(nona): Add browser tests for other API as well.
390 SCOPED_TRACE("commitText test");
391 mock_input_context->Reset();
392 mock_candidate_window->Reset();
394 const char commit_text_test_script[] =
395 "chrome.input.ime.commitText({"
396 " contextID: engineBridge.getFocusedContextID().contextID,"
397 " text:'COMMIT_TEXT'"
398 "});";
400 ASSERT_TRUE(content::ExecuteScript(host->host_contents(),
401 commit_text_test_script));
402 EXPECT_EQ(1, mock_input_context->commit_text_call_count());
403 EXPECT_EQ("COMMIT_TEXT", mock_input_context->last_commit_text());
406 SCOPED_TRACE("sendKeyEvents test");
407 mock_input_context->Reset();
408 mock_candidate_window->Reset();
410 const char send_key_events_test_script[] =
411 "chrome.input.ime.sendKeyEvents({"
412 " contextID: engineBridge.getFocusedContextID().contextID,"
413 " keyData : [{"
414 " type : 'keydown',"
415 " requestId : '0',"
416 " key : 'z',"
417 " code : 'KeyZ',"
418 " },{"
419 " type : 'keyup',"
420 " requestId : '1',"
421 " key : 'z',"
422 " code : 'KeyZ',"
423 " }]"
424 "});";
426 ExtensionTestMessageListener keyevent_listener_down(
427 "onKeyEvent:keydown:z:KeyZ:false:false:false:false", false);
428 ExtensionTestMessageListener keyevent_listener_up(
429 "onKeyEvent:keyup:z:KeyZ:false:false:false:false", false);
431 ASSERT_TRUE(content::ExecuteScript(host->host_contents(),
432 send_key_events_test_script));
434 ASSERT_TRUE(keyevent_listener_down.WaitUntilSatisfied());
435 EXPECT_TRUE(keyevent_listener_down.was_satisfied());
436 ASSERT_TRUE(keyevent_listener_up.WaitUntilSatisfied());
437 EXPECT_TRUE(keyevent_listener_up.was_satisfied());
440 SCOPED_TRACE("setComposition test");
441 mock_input_context->Reset();
442 mock_candidate_window->Reset();
444 const char set_composition_test_script[] =
445 "chrome.input.ime.setComposition({"
446 " contextID: engineBridge.getFocusedContextID().contextID,"
447 " text:'COMPOSITION_TEXT',"
448 " cursor:4,"
449 " segments : [{"
450 " start: 0,"
451 " end: 5,"
452 " style: 'underline'"
453 " },{"
454 " start: 6,"
455 " end: 10,"
456 " style: 'doubleUnderline'"
457 " }]"
458 "});";
460 ASSERT_TRUE(content::ExecuteScript(host->host_contents(),
461 set_composition_test_script));
462 EXPECT_EQ(1, mock_input_context->update_preedit_text_call_count());
464 EXPECT_EQ(4U, mock_input_context->last_update_preedit_arg().cursor_pos);
465 EXPECT_TRUE(mock_input_context->last_update_preedit_arg().is_visible);
467 const IBusText& ibus_text =
468 mock_input_context->last_update_preedit_arg().ibus_text;
469 EXPECT_EQ("COMPOSITION_TEXT", ibus_text.text());
470 const std::vector<IBusText::UnderlineAttribute>& underlines =
471 ibus_text.underline_attributes();
473 ASSERT_EQ(2U, underlines.size());
474 EXPECT_EQ(IBusText::IBUS_TEXT_UNDERLINE_SINGLE, underlines[0].type);
475 EXPECT_EQ(0U, underlines[0].start_index);
476 EXPECT_EQ(5U, underlines[0].end_index);
478 EXPECT_EQ(IBusText::IBUS_TEXT_UNDERLINE_DOUBLE, underlines[1].type);
479 EXPECT_EQ(6U, underlines[1].start_index);
480 EXPECT_EQ(10U, underlines[1].end_index);
483 SCOPED_TRACE("clearComposition test");
484 mock_input_context->Reset();
485 mock_candidate_window->Reset();
487 const char commite_text_test_script[] =
488 "chrome.input.ime.clearComposition({"
489 " contextID: engineBridge.getFocusedContextID().contextID,"
490 "});";
492 ASSERT_TRUE(content::ExecuteScript(host->host_contents(),
493 commite_text_test_script));
494 EXPECT_EQ(1, mock_input_context->update_preedit_text_call_count());
495 EXPECT_FALSE(mock_input_context->last_update_preedit_arg().is_visible);
496 const IBusText& ibus_text =
497 mock_input_context->last_update_preedit_arg().ibus_text;
498 EXPECT_TRUE(ibus_text.text().empty());
501 SCOPED_TRACE("setCandidateWindowProperties:visibility test");
502 mock_input_context->Reset();
503 mock_candidate_window->Reset();
505 const char set_candidate_window_properties_test_script[] =
506 "chrome.input.ime.setCandidateWindowProperties({"
507 " engineID: engineBridge.getActiveEngineID(),"
508 " properties: {"
509 " visible: true,"
510 " }"
511 "});";
512 ASSERT_TRUE(content::ExecuteScript(
513 host->host_contents(),
514 set_candidate_window_properties_test_script));
515 EXPECT_EQ(1, mock_candidate_window->update_lookup_table_call_count());
516 EXPECT_TRUE(
517 mock_candidate_window->last_update_lookup_table_arg().is_visible);
520 SCOPED_TRACE("setCandidateWindowProperties:cursor_visibility test");
521 mock_input_context->Reset();
522 mock_candidate_window->Reset();
524 const char set_candidate_window_properties_test_script[] =
525 "chrome.input.ime.setCandidateWindowProperties({"
526 " engineID: engineBridge.getActiveEngineID(),"
527 " properties: {"
528 " cursorVisible: true,"
529 " }"
530 "});";
531 ASSERT_TRUE(content::ExecuteScript(
532 host->host_contents(),
533 set_candidate_window_properties_test_script));
534 EXPECT_EQ(1, mock_candidate_window->update_lookup_table_call_count());
536 // window visibility is kept as before.
537 EXPECT_TRUE(
538 mock_candidate_window->last_update_lookup_table_arg().is_visible);
540 const ui::CandidateWindow& table =
541 mock_candidate_window->last_update_lookup_table_arg().lookup_table;
542 EXPECT_TRUE(table.is_cursor_visible());
545 SCOPED_TRACE("setCandidateWindowProperties:vertical test");
546 mock_input_context->Reset();
547 mock_candidate_window->Reset();
549 const char set_candidate_window_properties_test_script[] =
550 "chrome.input.ime.setCandidateWindowProperties({"
551 " engineID: engineBridge.getActiveEngineID(),"
552 " properties: {"
553 " vertical: true,"
554 " }"
555 "});";
556 ASSERT_TRUE(content::ExecuteScript(
557 host->host_contents(),
558 set_candidate_window_properties_test_script));
559 EXPECT_EQ(1, mock_candidate_window->update_lookup_table_call_count());
561 // window visibility is kept as before.
562 EXPECT_TRUE(
563 mock_candidate_window->last_update_lookup_table_arg().is_visible);
565 const ui::CandidateWindow& table =
566 mock_candidate_window->last_update_lookup_table_arg().lookup_table;
568 // cursor visibility is kept as before.
569 EXPECT_TRUE(table.is_cursor_visible());
571 EXPECT_EQ(ui::CandidateWindow::VERTICAL, table.orientation());
574 SCOPED_TRACE("setCandidateWindowProperties:pageSize test");
575 mock_input_context->Reset();
576 mock_candidate_window->Reset();
578 const char set_candidate_window_properties_test_script[] =
579 "chrome.input.ime.setCandidateWindowProperties({"
580 " engineID: engineBridge.getActiveEngineID(),"
581 " properties: {"
582 " pageSize: 7,"
583 " }"
584 "});";
585 ASSERT_TRUE(content::ExecuteScript(
586 host->host_contents(),
587 set_candidate_window_properties_test_script));
588 EXPECT_EQ(1, mock_candidate_window->update_lookup_table_call_count());
590 // window visibility is kept as before.
591 EXPECT_TRUE(
592 mock_candidate_window->last_update_lookup_table_arg().is_visible);
594 const ui::CandidateWindow& table =
595 mock_candidate_window->last_update_lookup_table_arg().lookup_table;
597 // cursor visibility is kept as before.
598 EXPECT_TRUE(table.is_cursor_visible());
600 // oritantation is kept as before.
601 EXPECT_EQ(ui::CandidateWindow::VERTICAL, table.orientation());
603 EXPECT_EQ(7U, table.page_size());
606 SCOPED_TRACE("setCandidateWindowProperties:auxTextVisibility test");
607 mock_input_context->Reset();
608 mock_candidate_window->Reset();
610 const char set_candidate_window_properties_test_script[] =
611 "chrome.input.ime.setCandidateWindowProperties({"
612 " engineID: engineBridge.getActiveEngineID(),"
613 " properties: {"
614 " auxiliaryTextVisible: true"
615 " }"
616 "});";
617 ASSERT_TRUE(content::ExecuteScript(
618 host->host_contents(),
619 set_candidate_window_properties_test_script));
620 EXPECT_EQ(1, mock_candidate_window->update_lookup_table_call_count());
622 const ui::CandidateWindow& table =
623 mock_candidate_window->last_update_lookup_table_arg().lookup_table;
624 EXPECT_TRUE(table.is_auxiliary_text_visible());
627 SCOPED_TRACE("setCandidateWindowProperties:auxText test");
628 mock_input_context->Reset();
629 mock_candidate_window->Reset();
631 const char set_candidate_window_properties_test_script[] =
632 "chrome.input.ime.setCandidateWindowProperties({"
633 " engineID: engineBridge.getActiveEngineID(),"
634 " properties: {"
635 " auxiliaryText: 'AUXILIARY_TEXT'"
636 " }"
637 "});";
638 ASSERT_TRUE(content::ExecuteScript(
639 host->host_contents(),
640 set_candidate_window_properties_test_script));
641 EXPECT_EQ(1, mock_candidate_window->update_lookup_table_call_count());
643 // aux text visibility is kept as before.
644 const ui::CandidateWindow& table =
645 mock_candidate_window->last_update_lookup_table_arg().lookup_table;
646 EXPECT_TRUE(table.is_auxiliary_text_visible());
647 EXPECT_EQ("AUXILIARY_TEXT", table.auxiliary_text());
650 SCOPED_TRACE("setCandidates test");
651 mock_input_context->Reset();
652 mock_candidate_window->Reset();
654 const char set_candidates_test_script[] =
655 "chrome.input.ime.setCandidates({"
656 " contextID: engineBridge.getFocusedContextID().contextID,"
657 " candidates: [{"
658 " candidate: 'CANDIDATE_1',"
659 " id: 1,"
660 " },{"
661 " candidate: 'CANDIDATE_2',"
662 " id: 2,"
663 " label: 'LABEL_2',"
664 " },{"
665 " candidate: 'CANDIDATE_3',"
666 " id: 3,"
667 " label: 'LABEL_3',"
668 " annotation: 'ANNOTACTION_3'"
669 " },{"
670 " candidate: 'CANDIDATE_4',"
671 " id: 4,"
672 " label: 'LABEL_4',"
673 " annotation: 'ANNOTACTION_4',"
674 " usage: {"
675 " title: 'TITLE_4',"
676 " body: 'BODY_4'"
677 " }"
678 " }]"
679 "});";
680 ASSERT_TRUE(content::ExecuteScript(host->host_contents(),
681 set_candidates_test_script));
683 // window visibility is kept as before.
684 EXPECT_TRUE(
685 mock_candidate_window->last_update_lookup_table_arg().is_visible);
687 const ui::CandidateWindow& table =
688 mock_candidate_window->last_update_lookup_table_arg().lookup_table;
690 // cursor visibility is kept as before.
691 EXPECT_TRUE(table.is_cursor_visible());
693 // oritantation is kept as before.
694 EXPECT_EQ(ui::CandidateWindow::VERTICAL, table.orientation());
696 // page size is kept as before.
697 EXPECT_EQ(7U, table.page_size());
699 ASSERT_EQ(4U, table.candidates().size());
701 EXPECT_EQ("CANDIDATE_1", table.candidates().at(0).value);
703 EXPECT_EQ("CANDIDATE_2", table.candidates().at(1).value);
704 EXPECT_EQ("LABEL_2", table.candidates().at(1).label);
706 EXPECT_EQ("CANDIDATE_3", table.candidates().at(2).value);
707 EXPECT_EQ("LABEL_3", table.candidates().at(2).label);
708 EXPECT_EQ("ANNOTACTION_3", table.candidates().at(2).annotation);
710 EXPECT_EQ("CANDIDATE_4", table.candidates().at(3).value);
711 EXPECT_EQ("LABEL_4", table.candidates().at(3).label);
712 EXPECT_EQ("ANNOTACTION_4", table.candidates().at(3).annotation);
713 EXPECT_EQ("TITLE_4", table.candidates().at(3).description_title);
714 EXPECT_EQ("BODY_4", table.candidates().at(3).description_body);
717 SCOPED_TRACE("setCursorPosition test");
718 mock_input_context->Reset();
719 mock_candidate_window->Reset();
721 const char set_cursor_position_test_script[] =
722 "chrome.input.ime.setCursorPosition({"
723 " contextID: engineBridge.getFocusedContextID().contextID,"
724 " candidateID: 2"
725 "});";
726 ASSERT_TRUE(content::ExecuteScript(
727 host->host_contents(), set_cursor_position_test_script));
728 EXPECT_EQ(1, mock_candidate_window->update_lookup_table_call_count());
730 // window visibility is kept as before.
731 EXPECT_TRUE(
732 mock_candidate_window->last_update_lookup_table_arg().is_visible);
734 const ui::CandidateWindow& table =
735 mock_candidate_window->last_update_lookup_table_arg().lookup_table;
737 // cursor visibility is kept as before.
738 EXPECT_TRUE(table.is_cursor_visible());
740 // oritantation is kept as before.
741 EXPECT_EQ(ui::CandidateWindow::VERTICAL, table.orientation());
743 // page size is kept as before.
744 EXPECT_EQ(7U, table.page_size());
746 // candidates are same as before.
747 ASSERT_EQ(4U, table.candidates().size());
749 // Candidate ID == 2 is 1 in index.
750 EXPECT_EQ(1U, table.cursor_position());
753 SCOPED_TRACE("setMenuItem test");
754 mock_input_context->Reset();
755 mock_candidate_window->Reset();
757 const char set_menu_item_test_script[] =
758 "chrome.input.ime.setMenuItems({"
759 " engineID: engineBridge.getActiveEngineID(),"
760 " items: [{"
761 " id: 'ID0',"
762 " },{"
763 " id: 'ID1',"
764 " label: 'LABEL1',"
765 " },{"
766 " id: 'ID2',"
767 " label: 'LABEL2',"
768 " style: 'radio',"
769 " },{"
770 " id: 'ID3',"
771 " label: 'LABEL3',"
772 " style: 'check',"
773 " visible: true,"
774 " },{"
775 " id: 'ID4',"
776 " label: 'LABEL4',"
777 " style: 'separator',"
778 " visible: true,"
779 " checked: true"
780 " }]"
781 "});";
782 ASSERT_TRUE(content::ExecuteScript(
783 host->host_contents(), set_menu_item_test_script));
785 const InputMethodPropertyList& props =
786 InputMethodManager::Get()->GetCurrentInputMethodProperties();
787 ASSERT_EQ(5U, props.size());
789 EXPECT_EQ("ID0", props[0].key);
790 EXPECT_EQ("ID1", props[1].key);
791 EXPECT_EQ("ID2", props[2].key);
792 EXPECT_EQ("ID3", props[3].key);
793 EXPECT_EQ("ID4", props[4].key);
795 EXPECT_EQ("LABEL1", props[1].label);
796 EXPECT_EQ("LABEL2", props[2].label);
797 EXPECT_EQ("LABEL3", props[3].label);
798 EXPECT_EQ("LABEL4", props[4].label);
800 EXPECT_TRUE(props[2].is_selection_item);
801 // TODO(nona): Add tests for style: ["toggle" and "separator"]
802 // and visible:, when implement them.
804 EXPECT_TRUE(props[4].is_selection_item_checked);
807 SCOPED_TRACE("deleteSurroundingText test");
808 mock_input_context->Reset();
809 mock_candidate_window->Reset();
811 const char delete_surrounding_text_test_script[] =
812 "chrome.input.ime.deleteSurroundingText({"
813 " engineID: engineBridge.getActiveEngineID(),"
814 " contextID: engineBridge.getFocusedContextID().contextID,"
815 " offset: 5,"
816 " length: 3"
817 "});";
818 ASSERT_TRUE(content::ExecuteScript(
819 host->host_contents(), delete_surrounding_text_test_script));
821 EXPECT_EQ(1, mock_input_context->delete_surrounding_text_call_count());
822 EXPECT_EQ(5, mock_input_context->last_delete_surrounding_text_arg().offset);
823 EXPECT_EQ(3U,
824 mock_input_context->last_delete_surrounding_text_arg().length);
827 SCOPED_TRACE("onFocus test");
828 mock_input_context->Reset();
829 mock_candidate_window->Reset();
832 ExtensionTestMessageListener focus_listener("onFocus:text", false);
833 IBusEngineHandlerInterface::InputContext context(
834 ui::TEXT_INPUT_TYPE_TEXT, ui::TEXT_INPUT_MODE_DEFAULT);
835 engine_handler->FocusIn(context);
836 ASSERT_TRUE(focus_listener.WaitUntilSatisfied());
837 ASSERT_TRUE(focus_listener.was_satisfied());
840 ExtensionTestMessageListener focus_listener("onFocus:search", false);
841 IBusEngineHandlerInterface::InputContext context(
842 ui::TEXT_INPUT_TYPE_SEARCH, ui::TEXT_INPUT_MODE_DEFAULT);
843 engine_handler->FocusIn(context);
844 ASSERT_TRUE(focus_listener.WaitUntilSatisfied());
845 ASSERT_TRUE(focus_listener.was_satisfied());
848 ExtensionTestMessageListener focus_listener("onFocus:tel", false);
849 IBusEngineHandlerInterface::InputContext context(
850 ui::TEXT_INPUT_TYPE_TELEPHONE, ui::TEXT_INPUT_MODE_DEFAULT);
851 engine_handler->FocusIn(context);
852 ASSERT_TRUE(focus_listener.WaitUntilSatisfied());
853 ASSERT_TRUE(focus_listener.was_satisfied());
856 ExtensionTestMessageListener focus_listener("onFocus:url", false);
857 IBusEngineHandlerInterface::InputContext context(
858 ui::TEXT_INPUT_TYPE_URL, ui::TEXT_INPUT_MODE_DEFAULT);
859 engine_handler->FocusIn(context);
860 ASSERT_TRUE(focus_listener.WaitUntilSatisfied());
861 ASSERT_TRUE(focus_listener.was_satisfied());
864 ExtensionTestMessageListener focus_listener("onFocus:email", false);
865 IBusEngineHandlerInterface::InputContext context(
866 ui::TEXT_INPUT_TYPE_EMAIL, ui::TEXT_INPUT_MODE_DEFAULT);
867 engine_handler->FocusIn(context);
868 ASSERT_TRUE(focus_listener.WaitUntilSatisfied());
869 ASSERT_TRUE(focus_listener.was_satisfied());
872 ExtensionTestMessageListener focus_listener("onFocus:number", false);
873 IBusEngineHandlerInterface::InputContext context(
874 ui::TEXT_INPUT_TYPE_NUMBER, ui::TEXT_INPUT_MODE_DEFAULT);
875 engine_handler->FocusIn(context);
876 ASSERT_TRUE(focus_listener.WaitUntilSatisfied());
877 ASSERT_TRUE(focus_listener.was_satisfied());
881 IBusBridge::Get()->SetInputContextHandler(NULL);
882 IBusBridge::Get()->SetCandidateWindowHandler(NULL);
885 } // namespace
886 } // namespace input_method
887 } // namespace chromeos