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"
21 namespace input_method
{
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.
35 kTestTypeIncognito
= 1,
36 kTestTypeComponent
= 2,
39 class InputMethodEngineIBusBrowserTest
40 : public ExtensionBrowserTest
,
41 public ::testing::WithParamInterface
<TestType
> {
43 InputMethodEngineIBusBrowserTest()
44 : ExtensionBrowserTest() {}
45 virtual ~InputMethodEngineIBusBrowserTest() {}
47 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE
{
48 ExtensionBrowserTest::SetUpInProcessBrowserTestFixture();
51 virtual void TearDownInProcessBrowserTestFixture() OVERRIDE
{
56 void LoadTestInputMethod() {
57 // This will load "chrome/test/data/extensions/input_ime"
58 ExtensionTestMessageListener
ime_ready_listener("ReadyToUseImeEvent",
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
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
) {
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
));
111 const extensions::Extension
* extension_
;
114 class KeyEventDoneCallback
{
116 explicit KeyEventDoneCallback(bool expected_argument
)
117 : expected_argument_(expected_argument
),
119 ~KeyEventDoneCallback() {}
121 void Run(bool consumed
) {
122 if (consumed
== expected_argument_
) {
123 base::MessageLoop::current()->Quit();
128 void WaitUntilCalled() {
130 content::RunMessageLoop();
134 bool expected_argument_
;
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
,
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
,
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
,
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
,
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
,
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
,
341 ui::EF_CAPS_LOCK_DOWN
,
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
,
360 ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
,
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
,
379 ui::EF_SHIFT_DOWN
| ui::EF_CAPS_LOCK_DOWN
,
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'"
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,"
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',"
452 " style: 'underline'"
456 " style: 'doubleUnderline'"
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,"
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(),"
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());
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(),"
528 " cursorVisible: true,"
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.
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(),"
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.
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(),"
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.
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(),"
614 " auxiliaryTextVisible: true"
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(),"
635 " auxiliaryText: 'AUXILIARY_TEXT'"
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,"
658 " candidate: 'CANDIDATE_1',"
661 " candidate: 'CANDIDATE_2',"
665 " candidate: 'CANDIDATE_3',"
668 " annotation: 'ANNOTACTION_3'"
670 " candidate: 'CANDIDATE_4',"
673 " annotation: 'ANNOTACTION_4',"
680 ASSERT_TRUE(content::ExecuteScript(host
->host_contents(),
681 set_candidates_test_script
));
683 // window visibility is kept as before.
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,"
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.
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(),"
777 " style: 'separator',"
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,"
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
);
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
);
886 } // namespace input_method
887 } // namespace chromeos