Skip to content

Commit 711eeaa

Browse files
committed
Added test cases.
1 parent 4a9f770 commit 711eeaa

3 files changed

Lines changed: 135 additions & 23 deletions

File tree

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
[
2+
{ "action": "waitForIdle" },
3+
{ "action": "screenshot", "id": "01-startup" },
4+
5+
{ "action": "showView", "idRef": "com.microsoft.copilot.eclipse.ui.chat.ChatView" },
6+
{ "action": "waitForIdle" },
7+
{ "action": "screenshot", "id": "02-chat-open" },
8+
9+
{ "action": "assertExists",
10+
"locator": { "by": "viewId", "id": "com.microsoft.copilot.eclipse.ui.chat.ChatView" } },
11+
12+
{ "action": "waitFor",
13+
"locator": { "by": "widgetId", "value": "chat-input" },
14+
"timeoutSec": 30 },
15+
16+
{ "action": "waitForMethod",
17+
"locator": { "by": "widgetId", "value": "model-picker" },
18+
"method": "getSelectedItemId",
19+
"timeoutSec": 60 },
20+
21+
{ "action": "assertExists",
22+
"locator": { "by": "widgetId", "value": "model-picker" } },
23+
{ "action": "assertExists",
24+
"locator": { "by": "widgetId", "value": "mode-picker" } },
25+
{ "action": "screenshot", "id": "03-pickers-before" },
26+
27+
{ "action": "click", "locator": { "by": "widgetId", "value": "chat-input" } },
28+
{ "action": "clearElement", "locator": { "by": "widgetId", "value": "chat-input" } },
29+
{ "action": "typeIn",
30+
"locator": { "by": "widgetId", "value": "chat-input" },
31+
"text": "Line 1 of a long message\nLine 2 of a long message\nLine 3 of a long message\nLine 4 of a long message\nLine 5 of a long message\nLine 6 of a long message\nLine 7 of a long message" },
32+
{ "action": "screenshot", "id": "04-long-message-typed" },
33+
34+
{ "action": "waitFor",
35+
"locator": { "by": "buttonWithTooltip", "tooltip": "Send" },
36+
"timeoutSec": 30 },
37+
{ "action": "click",
38+
"locator": { "by": "buttonWithTooltip", "tooltip": "Send" } },
39+
40+
{ "action": "waitFor",
41+
"locator": { "by": "widgetId", "value": "user-turn" },
42+
"timeoutSec": 30 },
43+
{ "action": "waitFor",
44+
"locator": { "by": "cssClass", "value": "model-info-label" },
45+
"timeoutSec": 120 },
46+
{ "action": "screenshot", "id": "05-first-response" },
47+
48+
{ "action": "click", "locator": { "by": "widgetId", "value": "chat-input" } },
49+
50+
{ "action": "pressKey",
51+
"key": "ARROW_UP",
52+
"locator": { "by": "widgetId", "value": "chat-input" } },
53+
{ "action": "waitForIdle" },
54+
{ "action": "screenshot", "id": "06-after-history-recall" },
55+
56+
{ "action": "assertExists",
57+
"locator": { "by": "widgetId", "value": "model-picker" } },
58+
{ "action": "assertExists",
59+
"locator": { "by": "widgetId", "value": "mode-picker" } },
60+
{ "action": "screenshot", "id": "07-pickers-after-history" }
61+
]

com.microsoft.copilot.eclipse.swtbot.test/src/com/microsoft/copilot/eclipse/swtbot/test/probe/StepExecutor.java

Lines changed: 63 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@
1717
import javax.imageio.ImageIO;
1818

1919
import org.eclipse.core.commands.ParameterizedCommand;
20+
import org.eclipse.swt.SWT;
2021
import org.eclipse.swt.graphics.Rectangle;
2122
import org.eclipse.swt.widgets.Display;
23+
import org.eclipse.swt.widgets.Event;
2224
import org.eclipse.swt.widgets.Shell;
2325
import org.eclipse.swt.widgets.Widget;
2426
import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
25-
import org.eclipse.swtbot.swt.finder.keyboard.Keystrokes;
2627
import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences;
2728
import org.eclipse.swtbot.swt.finder.widgets.SWTBotStyledText;
2829
import org.eclipse.swtbot.swt.finder.widgets.SWTBotText;
@@ -104,7 +105,7 @@ void execute(ProbeStep step, StepResult result) throws Exception {
104105
dumpUi(step, result);
105106
break;
106107
case "newSession":
107-
invokeCommand("com.microsoft.copilot.eclipse.commands.newChatSession");
108+
invokeCommand("com.microsoft.copilot.eclipse.commands.newConversation");
108109
break;
109110
default:
110111
throw new IllegalArgumentException("Unknown action: " + action);
@@ -205,41 +206,57 @@ private void waitForIdle() {
205206

206207
private void pressKey(ProbeStep step) {
207208
String key = required(step.key, "key");
208-
org.eclipse.jface.bindings.keys.KeyStroke stroke = toKeystroke(key);
209+
int keyCode = toSwtKeyCode(key);
210+
// Validate the locator resolves (guards against authoring errors).
211+
// Focus management is the caller's responsibility via a preceding click action.
209212
if (step.locator != null) {
210-
Object widget = resolve(step.locator);
211-
if (widget instanceof SWTBotStyledText) {
212-
((SWTBotStyledText) widget).pressShortcut(stroke);
213-
return;
214-
}
215-
if (widget instanceof SWTBotText) {
216-
((SWTBotText) widget).pressShortcut(stroke);
217-
return;
218-
}
219-
// Fall through to shell-level press if the widget wrapper lacks pressShortcut.
213+
resolve(step.locator);
220214
}
221-
bot.activeShell().pressShortcut(stroke);
215+
Display display = Display.getDefault();
216+
display.syncExec(() -> postKey(display, keyCode));
217+
}
218+
219+
private static void postKey(Display display, int keyCode) {
220+
Event down = new Event();
221+
down.type = SWT.KeyDown;
222+
down.keyCode = keyCode;
223+
display.post(down);
224+
Event up = new Event();
225+
up.type = SWT.KeyUp;
226+
up.keyCode = keyCode;
227+
display.post(up);
222228
}
223229

224-
private static org.eclipse.jface.bindings.keys.KeyStroke toKeystroke(String key) {
225-
String upper = key.toUpperCase();
226-
switch (upper) {
230+
private static int toSwtKeyCode(String key) {
231+
switch (key.toUpperCase()) {
227232
case "ENTER":
228233
case "RETURN":
229234
case "CR":
230-
return Keystrokes.CR;
235+
return SWT.CR;
231236
case "ESC":
232237
case "ESCAPE":
233-
return Keystrokes.ESC;
238+
return SWT.ESC;
234239
case "TAB":
235-
return Keystrokes.TAB;
240+
return SWT.TAB;
236241
case "SPACE":
237-
return Keystrokes.SPACE;
242+
return SWT.SPACE;
238243
case "BACKSPACE":
239244
case "BS":
240-
return Keystrokes.BS;
245+
return SWT.BS;
241246
case "DELETE":
242-
return Keystrokes.DELETE;
247+
return SWT.DEL;
248+
case "UP":
249+
case "ARROW_UP":
250+
return SWT.ARROW_UP;
251+
case "DOWN":
252+
case "ARROW_DOWN":
253+
return SWT.ARROW_DOWN;
254+
case "LEFT":
255+
case "ARROW_LEFT":
256+
return SWT.ARROW_LEFT;
257+
case "RIGHT":
258+
case "ARROW_RIGHT":
259+
return SWT.ARROW_RIGHT;
243260
default:
244261
throw new IllegalArgumentException("Unsupported key: " + key);
245262
}
@@ -369,6 +386,15 @@ private void click(ProbeStep step) {
369386
((SWTBotText) widget).setFocus();
370387
return;
371388
}
389+
if (widget instanceof org.eclipse.swt.custom.StyledText) {
390+
org.eclipse.swt.custom.StyledText st = (org.eclipse.swt.custom.StyledText) widget;
391+
Display.getDefault().syncExec(() -> {
392+
if (!st.isDisposed()) {
393+
st.setFocus();
394+
}
395+
});
396+
return;
397+
}
372398
invokeClick(widget);
373399
}
374400

@@ -379,6 +405,13 @@ private void typeIn(ProbeStep step) {
379405
((SWTBotText) widget).setText(payload);
380406
} else if (widget instanceof SWTBotStyledText) {
381407
((SWTBotStyledText) widget).setText(payload);
408+
} else if (widget instanceof org.eclipse.swt.custom.StyledText) {
409+
org.eclipse.swt.custom.StyledText st = (org.eclipse.swt.custom.StyledText) widget;
410+
Display.getDefault().syncExec(() -> {
411+
if (!st.isDisposed()) {
412+
st.setText(payload);
413+
}
414+
});
382415
} else {
383416
throw new IllegalArgumentException(
384417
"typeIn not supported for widget type: " + widget.getClass().getSimpleName());
@@ -391,6 +424,13 @@ private void clearElement(ProbeStep step) {
391424
((SWTBotText) widget).setText("");
392425
} else if (widget instanceof SWTBotStyledText) {
393426
((SWTBotStyledText) widget).setText("");
427+
} else if (widget instanceof org.eclipse.swt.custom.StyledText) {
428+
org.eclipse.swt.custom.StyledText st = (org.eclipse.swt.custom.StyledText) widget;
429+
Display.getDefault().syncExec(() -> {
430+
if (!st.isDisposed()) {
431+
st.setText("");
432+
}
433+
});
394434
} else {
395435
throw new IllegalArgumentException(
396436
"clearElement not supported for widget type: " + widget.getClass().getSimpleName());

com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/ActionBar.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,16 @@ public ActionBar(Composite parent, int style, ChatServiceManager chatServiceMana
216216

217217
ChatInputTextViewer tv = new ChatInputTextViewer(borderedActionBar, chatServiceManager);
218218
tv.setEditable(true);
219+
// Relayout the chat view container (this ActionBar's parent) when the input height changes
220+
tv.setLayoutRefresher(() -> {
221+
if (ActionBar.this.isDisposed()) {
222+
return;
223+
}
224+
Composite chatViewParent = ActionBar.this.getParent();
225+
if (chatViewParent != null && !chatViewParent.isDisposed()) {
226+
chatViewParent.requestLayout();
227+
}
228+
});
219229
// Relayout the chat view container (this ActionBar's parent) when the input height changes,
220230
// so the bottom picker/action row remains visible even for tall inputs (e.g. long history recall).
221231
tv.setLayoutRefresher(() -> {
@@ -519,6 +529,7 @@ private void setUpChatModePicker(Composite parent) {
519529
this.modePickerButton.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false, false));
520530
this.modePickerButton.setToolTipText(Messages.chat_actionBar_modePicker_Tooltip);
521531
this.modePickerButton.setAccessibilityName("chat mode picker");
532+
this.modePickerButton.setData("org.eclipse.swtbot.widget.key", "mode-picker");
522533
UserPreferenceService userPreferenceService = chatServiceManager.getUserPreferenceService();
523534
userPreferenceService.bindChatModePicker(this.modePickerButton);
524535

0 commit comments

Comments
 (0)