Skip to content

Commit dc40830

Browse files
jtpioarjxn-py
authored andcommitted
Restore auto-resizing of the code console input prompts (jupyterlab#17819)
* Auto-resize the code console input prompts * Add UI test * Handle moving the prompt cell with code in it * timeout * try to improve the resize logic * improve UX * fix jittering * integrity * more integrity fixes * fix promptCell * fix package.json * stabilize tests * snapshot update
1 parent a09dca6 commit dc40830

File tree

9 files changed

+400
-13
lines changed

9 files changed

+400
-13
lines changed
-528 Bytes
Loading
-906 Bytes
Loading

galata/test/jupyterlab/console.test.ts

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,163 @@ test.describe('Console (terminal mode)', () => {
7272
await expect(executedCell).toContainText('4194304');
7373
});
7474
});
75+
76+
test.describe('Console Input Auto-Resize', () => {
77+
test.beforeEach(async ({ page }) => setupConsole(page));
78+
79+
test('Input prompt auto-resizes with multiple lines of text', async ({
80+
page
81+
}) => {
82+
const codeConsoleInput = page.locator('.jp-CodeConsole-input');
83+
84+
const initialHeight = await codeConsoleInput.boundingBox();
85+
expect(initialHeight).not.toBeNull();
86+
87+
const multiLineCode = `def hello_world():
88+
print("Hello")
89+
print("World")
90+
return "Done"`;
91+
92+
await page.keyboard.type(multiLineCode);
93+
94+
const afterTypingHeight = await codeConsoleInput.boundingBox();
95+
expect(afterTypingHeight).not.toBeNull();
96+
expect(afterTypingHeight!.height).toBeGreaterThan(initialHeight!.height);
97+
});
98+
99+
test('Input prompt auto-resize works with paste operations', async ({
100+
page
101+
}) => {
102+
const codeConsoleInput = page.locator('.jp-CodeConsole-input');
103+
104+
const initialHeight = await codeConsoleInput.boundingBox();
105+
expect(initialHeight).not.toBeNull();
106+
107+
const pastedCode = `import numpy as np
108+
import pandas as pd
109+
110+
data = pd.DataFrame({
111+
'x': [1, 2, 3, 4, 5],
112+
'y': [2, 4, 6, 8, 10]
113+
})
114+
115+
print(data.head())`;
116+
117+
await page.evaluate(async code => {
118+
await navigator.clipboard.writeText(code);
119+
}, pastedCode);
120+
121+
await page.keyboard.press('ControlOrMeta+v');
122+
123+
const afterPasteHeight = await codeConsoleInput.boundingBox();
124+
expect(afterPasteHeight).not.toBeNull();
125+
expect(afterPasteHeight!.height).toBeGreaterThan(initialHeight!.height);
126+
});
127+
128+
test('Input prompt maintains auto-resize height when moved from bottom to top', async ({
129+
page
130+
}) => {
131+
const codeConsoleInput = page.locator('.jp-CodeConsole-input');
132+
133+
const pastedCode = `def complex_function():
134+
for i in range(10):
135+
if i % 2 == 0:
136+
print(f"Even: {i}")
137+
else:
138+
print(f"Odd: {i}")
139+
return "Completed"`;
140+
141+
await page.evaluate(async code => {
142+
await navigator.clipboard.writeText(code);
143+
}, pastedCode);
144+
145+
await page.keyboard.press('ControlOrMeta+v');
146+
147+
const heightAtBottom = await codeConsoleInput.boundingBox();
148+
expect(heightAtBottom).not.toBeNull();
149+
150+
await page.getByLabel('Change Console Prompt Position').first().click();
151+
await page.getByText('Prompt to top').click();
152+
153+
const heightAtTop = await codeConsoleInput.boundingBox();
154+
expect(heightAtTop).not.toBeNull();
155+
expect(heightAtTop!.height).toBeCloseTo(heightAtBottom!.height, 1);
156+
});
157+
158+
test('Input prompt continues to auto-resize after code execution', async ({
159+
page
160+
}) => {
161+
const codeConsoleInput = page.locator('.jp-CodeConsole-input');
162+
163+
const initialHeight = await codeConsoleInput.boundingBox();
164+
expect(initialHeight).not.toBeNull();
165+
166+
const multiLineCode = `def test_function():
167+
print("Line 1")
168+
print("Line 2")
169+
return "Done"`;
170+
171+
await page.keyboard.type(multiLineCode);
172+
173+
const heightBeforeExecution = await codeConsoleInput.boundingBox();
174+
expect(heightBeforeExecution).not.toBeNull();
175+
expect(heightBeforeExecution!.height).toBeGreaterThan(
176+
initialHeight!.height
177+
);
178+
179+
// Execute the code
180+
await page.keyboard.press('Shift+Enter');
181+
182+
await page.locator('text=| Idle').waitFor();
183+
184+
// Check that the new empty input cell has shrunk back to original size
185+
const heightAfterExecution = await codeConsoleInput.boundingBox();
186+
expect(heightAfterExecution).not.toBeNull();
187+
expect(heightAfterExecution!.height).toBe(initialHeight!.height);
188+
189+
// Type new multi-line code in the new prompt cell
190+
const moreCode = `import os
191+
import sys
192+
print("Testing auto-resize")
193+
print("After execution")`;
194+
195+
await page.keyboard.type(moreCode);
196+
197+
const heightAfterTyping = await codeConsoleInput.boundingBox();
198+
expect(heightAfterTyping).not.toBeNull();
199+
200+
// The input should have grown again for the new multi-line content
201+
expect(heightAfterTyping!.height).toBeGreaterThan(
202+
heightAfterExecution!.height
203+
);
204+
});
205+
206+
test('Input prompt shrinks when content is cleared', async ({ page }) => {
207+
const codeConsoleInput = page.locator('.jp-CodeConsole-input');
208+
209+
const initialHeight = await codeConsoleInput.boundingBox();
210+
expect(initialHeight).not.toBeNull();
211+
212+
const multiLineCode = `def multi_line_function():
213+
print("This is line 1")
214+
print("This is line 2")
215+
print("This is line 3")
216+
for i in range(5):
217+
print(f"Loop iteration {i}")
218+
return "Finished"`;
219+
220+
await page.keyboard.type(multiLineCode);
221+
222+
const expandedHeight = await codeConsoleInput.boundingBox();
223+
expect(expandedHeight).not.toBeNull();
224+
expect(expandedHeight!.height).toBeGreaterThan(initialHeight!.height);
225+
226+
// Clear the input using Ctrl+A followed by Delete
227+
await page.keyboard.press('ControlOrMeta+a');
228+
await page.keyboard.press('Delete');
229+
230+
const shrunkHeight = await codeConsoleInput.boundingBox();
231+
expect(shrunkHeight).not.toBeNull();
232+
expect(shrunkHeight!.height).toBe(initialHeight!.height);
233+
});
234+
});

packages/console/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
"@jupyterlab/apputils": "^4.6.0",
4747
"@jupyterlab/cells": "^4.5.0",
4848
"@jupyterlab/codeeditor": "^4.5.0",
49+
"@jupyterlab/codemirror": "^4.5.0",
4950
"@jupyterlab/coreutils": "^6.5.0",
5051
"@jupyterlab/nbformat": "^4.5.0",
5152
"@jupyterlab/observables": "^5.5.0",
@@ -61,7 +62,6 @@
6162
"@lumino/widgets": "^2.7.2"
6263
},
6364
"devDependencies": {
64-
"@jupyterlab/codemirror": "^4.5.0",
6565
"@jupyterlab/testing": "^4.5.0",
6666
"@types/jest": "^29.2.0",
6767
"jest": "^29.2.0",

0 commit comments

Comments
 (0)