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();
+ });
});