From 77cd933939cb9b084e8c4ac3d6cfc0df1e6196c3 Mon Sep 17 00:00:00 2001 From: Oliver Eyton-Williams Date: Tue, 3 Feb 2026 17:14:07 +0100 Subject: [PATCH] test: check nothing unexpected appears in python terminal (#65572) --- .../templates/Challenges/classic/xterm.tsx | 6 ++- e2e/editor.spec.ts | 40 ++++++++++++++++++- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/client/src/templates/Challenges/classic/xterm.tsx b/client/src/templates/Challenges/classic/xterm.tsx index 8bb04f543aa..3e012885a1c 100644 --- a/client/src/templates/Challenges/classic/xterm.tsx +++ b/client/src/templates/Challenges/classic/xterm.tsx @@ -138,7 +138,11 @@ export const XtermTerminal = ({ }, [xtermFitRef, dimensions]); return ( -
+
); diff --git a/e2e/editor.spec.ts b/e2e/editor.spec.ts index 971f2bcaf96..22bc0109e21 100644 --- a/e2e/editor.spec.ts +++ b/e2e/editor.spec.ts @@ -31,6 +31,42 @@ test.describe('Editor Component', () => { }); test.describe('Python Terminal', () => { + test('should only have output if the python code generates it', async ({ + page, + browserName, + isMobile + }) => { + await page.goto( + 'learn/scientific-computing-with-python/learn-string-manipulation-by-building-a-cipher/step-2' + ); + + // First enter code that does not generate output + await focusEditor({ page, isMobile }); + await clearEditor({ page, browserName, isMobile }); + await getEditors(page).fill('no = "output"'); + + if (isMobile) await page.getByRole('tab', { name: 'Preview' }).click(); + + const terminal = page.getByTestId('xterm-terminal'); + // Ensure there is no output + await expect(async () => { + const text = await terminal.innerText(); + expect(text.trim()).toBe(''); + }).toPass(); + + if (isMobile) await page.getByRole('tab', { name: 'Code' }).click(); + + // Now enter code that does generate output + await focusEditor({ page, isMobile }); + await clearEditor({ page, browserName, isMobile }); + await getEditors(page).fill('some = "output"\nprint(some)'); + + if (isMobile) await page.getByRole('tab', { name: 'Preview' }).click(); + // Since the invisible characters are still there, we have to use "contain", + // not "have" + await expect(terminal).toContainText('output'); + }); + test('should display error message when the user enters invalid code', async ({ page, isMobile, @@ -49,12 +85,12 @@ test.describe('Python Terminal', () => { await page.getByRole('tab', { name: 'Preview' }).click(); } - const preview = page.getByTestId('preview-pane'); + const terminal = page.getByTestId('xterm-terminal'); // While it's displayed on multiple lines, the string itself has no newlines, hence: const error = `Traceback (most recent call last): File "main.py", line 1 def ^SyntaxError: invalid syntax`; // It shouldn't take this long, but the Python worker can be slow to respond. - await expect(preview.getByText(error)).toContainText(error, { + await expect(terminal.getByText(error)).toContainText(error, { timeout: 15000 }); });