From 6e33189f3b6f8dfd08b7735e5b8acd84272c7c76 Mon Sep 17 00:00:00 2001
From: Huyen Nguyen <25715018+huyenltnguyen@users.noreply.github.com>
Date: Sat, 25 Oct 2025 12:38:51 +0700
Subject: [PATCH] test(e2e): add tests for interactive editor toggle (#63043)
---
.../components/interactive-editor.tsx | 5 +-
.../src/templates/Challenges/generic/show.tsx | 5 +-
e2e/interactive-editor.spec.ts | 181 ++++++++++++++++++
3 files changed, 186 insertions(+), 5 deletions(-)
create mode 100644 e2e/interactive-editor.spec.ts
diff --git a/client/src/templates/Challenges/components/interactive-editor.tsx b/client/src/templates/Challenges/components/interactive-editor.tsx
index 12c836ddba4..fdca6a1e1bd 100644
--- a/client/src/templates/Challenges/components/interactive-editor.tsx
+++ b/client/src/templates/Challenges/components/interactive-editor.tsx
@@ -53,7 +53,10 @@ const InteractiveEditor = ({ files }: Props) => {
};
return (
-
+
-
+
{hasInteractiveEditor && (
{
+ test('should render paragraph nodules as text and not show the interactive editor toggle', 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 is a plain text paragraph.
'
+ },
+ {
+ type: 'paragraph',
+ data: 'Another paragraph with code in it.
'
+ }
+ ];
+
+ 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 is a plain text paragraph.')
+ ).toBeVisible();
+ await expect(
+ page.getByText('Another paragraph with code in it.')
+ ).toBeVisible();
+
+ await expect(
+ page.getByRole('button', { name: /interactive editor/i })
+ ).not.toBeVisible();
+ });
+
+ test('should toggle between interactive editor and static code view when Interactive Editor button is clicked', 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: 'Introduction paragraph.
'
+ },
+ {
+ type: 'interactiveEditor',
+ data: [
+ {
+ contents: 'console.log("Toggle test");',
+ ext: 'js',
+ name: 'script-1',
+ contentsHtml:
+ 'console.log("Toggle test");
'
+ },
+ {
+ contents: 'HTML content
',
+ ext: 'html',
+ name: 'index-1',
+ contentsHtml:
+ '<div>HTML content</div>
'
+ }
+ ]
+ },
+ {
+ type: 'paragraph',
+ data: 'Final paragraph.
'
+ }
+ ];
+
+ 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('Introduction paragraph.')).toBeVisible();
+ await expect(page.getByText('Final paragraph.')).toBeVisible();
+
+ // Initially, interactive editor should be hidden, static code view should be visible
+ await expect(page.getByTestId('sp-interactive-editor')).not.toBeVisible();
+ await expect(
+ page
+ .locator('pre code')
+ .filter({ hasText: 'console.log("Toggle test");' })
+ ).toHaveCount(1);
+ await expect(
+ page.locator('pre code').filter({ hasText: 'HTML content
' })
+ ).toHaveCount(1);
+ await expect(
+ page.evaluate(() => localStorage.getItem('showInteractiveEditor'))
+ ).resolves.toBe(null);
+
+ // Click the toggle button
+ const toggleButton = page.getByRole('button', {
+ name: /interactive editor/i
+ });
+ await toggleButton.click();
+
+ // Interactive editor should be visible, static code view hidden
+ await expect(page.getByTestId('sp-interactive-editor')).toBeVisible();
+ await expect(page.locator('pre code')).not.toBeVisible();
+ await expect(
+ page.evaluate(() => localStorage.getItem('showInteractiveEditor'))
+ ).resolves.toBe('true');
+
+ // Click the toggle button again
+ await toggleButton.click();
+
+ // Interactive editor should be hidden, static code view visible again
+ await expect(page.getByTestId('sp-interactive-editor')).not.toBeVisible();
+ await expect(
+ page
+ .locator('pre code')
+ .filter({ hasText: 'console.log("Toggle test");' })
+ ).toBeVisible();
+ await expect(
+ page.locator('pre code').filter({ hasText: 'HTML content
' })
+ ).toBeVisible();
+ await expect(
+ page.evaluate(() => localStorage.getItem('showInteractiveEditor'))
+ ).resolves.toBe('false');
+ });
+});