mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-04-30 16:01:14 -04:00
feat(client): Persist editor open tabs (#59103)
Co-authored-by: sembauke <semboot699@gmail.com>
This commit is contained in:
@@ -150,10 +150,30 @@ export const reducer = handleActions(
|
||||
? state.consoleOut
|
||||
: state.consoleOut.concat(payload, state.logsOut)
|
||||
}),
|
||||
[actionTypes.initVisibleEditors]: state => ({
|
||||
...state,
|
||||
visibleEditors: { [getTargetEditor(state.challengeFiles)]: true }
|
||||
}),
|
||||
[actionTypes.initVisibleEditors]: state => {
|
||||
let persistingVisibleEditors = {};
|
||||
const prevVisibleEditorKeys = Object.keys(state.visibleEditors);
|
||||
if (prevVisibleEditorKeys.length > 1) {
|
||||
// Restore states of relevant visible editors for the current challengeFiles
|
||||
persistingVisibleEditors = prevVisibleEditorKeys
|
||||
.filter(editorKey => {
|
||||
return state.challengeFiles.find(
|
||||
challengeFile => challengeFile.fileKey === editorKey
|
||||
);
|
||||
})
|
||||
.reduce((visibleEditors, key) => {
|
||||
visibleEditors[key] = state.visibleEditors[key];
|
||||
return visibleEditors;
|
||||
}, {});
|
||||
}
|
||||
return {
|
||||
...state,
|
||||
visibleEditors: {
|
||||
...persistingVisibleEditors,
|
||||
[getTargetEditor(state.challengeFiles)]: true
|
||||
}
|
||||
};
|
||||
},
|
||||
[actionTypes.updateChallengeMeta]: (state, { payload }) => ({
|
||||
...state,
|
||||
challengeMeta: { ...payload }
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"content": "<!DOCTYPE html><html lang=\"en\"><head><meta charset=\"utf-8\" /><title>Cafe Menu</title></head><body><main><h1>CAMPER CAFE</h1><p>Est. 2020</p><section><h2>Coffee</h2></section></main></body></html>"
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
import { getEditors } from './utils/editor';
|
||||
import { clearEditor, focusEditor, getEditors } from './utils/editor';
|
||||
import solution from './fixtures/learn-basic-css-by-building-a-cafe-menu-15.json';
|
||||
import { isMacOS } from './utils/user-agent';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto(
|
||||
@@ -72,4 +74,54 @@ test.describe('MultifileEditor Component', () => {
|
||||
|
||||
expect(await editorPane.getAttribute('style')).toBe(newStyle);
|
||||
});
|
||||
|
||||
test('Multiple open editors should remain open on moving to next challenge', async ({
|
||||
page,
|
||||
isMobile,
|
||||
browserName,
|
||||
context
|
||||
}) => {
|
||||
test.skip(
|
||||
browserName !== 'chromium',
|
||||
'Only chromium allows us to use the clipboard API.'
|
||||
);
|
||||
await context.grantPermissions(['clipboard-read', 'clipboard-write']);
|
||||
|
||||
await focusEditor({ page, isMobile });
|
||||
await clearEditor({ page, browserName });
|
||||
|
||||
await page.evaluate(
|
||||
async solution => await navigator.clipboard.writeText(solution.content),
|
||||
solution
|
||||
);
|
||||
|
||||
if (isMacOS) {
|
||||
await page.keyboard.press('Meta+v');
|
||||
} else {
|
||||
await page.keyboard.press('Control+v');
|
||||
}
|
||||
|
||||
const stylesEditor = page.getByRole('button', {
|
||||
name: 'styles.css Editor'
|
||||
});
|
||||
await stylesEditor.click();
|
||||
const editorsCurrentPage = getEditors(page);
|
||||
await expect(editorsCurrentPage).toHaveCount(2);
|
||||
|
||||
await page.keyboard.press('Control+Enter');
|
||||
|
||||
const submitButton = page.getByRole('button', {
|
||||
name: 'Submit and go to next challenge'
|
||||
});
|
||||
|
||||
// Mobile screen shifts submit button out of view and Playwright fails at scrolling with multiple editors open
|
||||
if (isMobile) {
|
||||
await submitButton.dispatchEvent('click');
|
||||
} else {
|
||||
await submitButton.click();
|
||||
}
|
||||
|
||||
const editorsNextPage = getEditors(page);
|
||||
await expect(editorsNextPage).toHaveCount(2);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user