diff --git a/client/src/templates/Challenges/components/interactive-editor.tsx b/client/src/templates/Challenges/components/interactive-editor.tsx index fdca6a1e1bd..49b70b39332 100644 --- a/client/src/templates/Challenges/components/interactive-editor.tsx +++ b/client/src/templates/Challenges/components/interactive-editor.tsx @@ -44,7 +44,11 @@ const InteractiveEditor = ({ files }: Props) => { return files.some(f => f.ext === ext); } - const showConsole = got('js') || got('ts'); + const hasHTML = got('html'); + const hasJavaScript = got('js') || got('ts') || got('jsx') || got('tsx'); + + const showConsole = hasJavaScript && hasHTML; + const layout = hasHTML ? 'preview' : 'console'; const freeCodeCampDarkSyntax = { ...freeCodeCampDark.syntax, punctuation: '#ffff00', @@ -84,7 +88,7 @@ const InteractiveEditor = ({ files }: Props) => { editorWidthPercentage: 60, showConsole: showConsole, showConsoleButton: showConsole, - layout: got('html') ? 'preview' : 'console', + layout: layout, showLineNumbers: true }} /> diff --git a/e2e/interactive-editor.spec.ts b/e2e/interactive-editor.spec.ts index 02f94ee81ef..0961ba5925d 100644 --- a/e2e/interactive-editor.spec.ts +++ b/e2e/interactive-editor.spec.ts @@ -178,4 +178,68 @@ test.describe('Interactive Editor', () => { page.evaluate(() => localStorage.getItem('showInteractiveEditor')) ).resolves.toBe('false'); }); + + test('should hide console panel in JS-only interactive editor to prevent output duplication', async ({ + page + }) => { + await page.route( + `**/page-data${challengePath}/page-data.json`, + async route => { + const response = await route.fetch(); + const body = await response.text(); + const pageData = JSON.parse(body) as PageData; + + pageData.result.data.challengeNode.challenge.title = challengeTitle; + pageData.result.data.challengeNode.challenge.nodules = [ + { + type: 'paragraph', + data: '

This challenge has only JavaScript code.

' + }, + { + type: 'interactiveEditor', + data: [ + { + contents: 'console.log("Hello from JS-only editor");', + ext: 'js', + name: 'script-1', + contentsHtml: + '
console.log("Hello from JS-only editor");
' + } + ] + } + ]; + + await route.fulfill({ + contentType: 'application/json', + body: JSON.stringify(pageData) + }); + } + ); + + await page.goto(challengePath); + + await expect( + page.getByRole('heading', { name: challengeTitle }) + ).toBeVisible(); + await expect( + page.getByText('This challenge has only JavaScript code.') + ).toBeVisible(); + + await expect( + page + .locator('pre code') + .filter({ hasText: 'console.log("Hello from JS-only editor");' }) + ).toBeVisible(); + + // Click the toggle button to show interactive editor + await page + .getByRole('button', { + name: /interactive editor/i + }) + .click(); + + // Check that the console is visible and the console wrapper is hidden + await expect(page.locator('.sp-console')).toBeVisible(); + await expect(page.locator('.sp-console-wrapper')).not.toBeVisible(); + }); });