fix: output console.logs as user types (DOM)

Any console.logs inside script tags will be written to the fcc console
as the user types.  DOM challenges only.

Also, DRYed out the main and test frame creation.
This commit is contained in:
Oliver Eyton-Williams
2019-11-01 13:02:23 +01:00
committed by mrugesh
parent 6acab90cb6
commit 29641986ab
3 changed files with 37 additions and 21 deletions

View File

@ -1,4 +1,5 @@
import {
all,
delay,
put,
select,
@ -124,20 +125,30 @@ function* previewChallengeSaga() {
if (!isBuildEnabled) {
return;
}
const challengeData = yield select(challengeDataSelector);
const consoleProxy = yield channel();
try {
yield put(initConsole(''));
yield put(initLogs());
yield fork(logToConsole, consoleProxy);
const proxyLogger = args => consoleProxy.put(args);
const challengeData = yield select(challengeDataSelector);
// try to build even if there's no preview so build errors will be reported.
const ctx = yield buildChallengeData(challengeData);
const buildData = yield buildChallengeData(challengeData);
// then only continue if there is a preview.
if (!challengeHasPreview(challengeData)) {
return;
}
const document = yield getContext('document');
yield call(updatePreview, ctx, document);
yield call(updatePreview, buildData, document, proxyLogger);
// We don't want to see the default console, so we initialise and output in
// one call.
yield all([put(initConsole('')), put(logsToConsole('// console output'))]);
} catch (err) {
console.error(err);
} finally {
consoleProxy.close();
}
}

View File

@ -159,10 +159,13 @@ export function buildBackendChallenge({ url }) {
};
}
export function updatePreview(buildData, document) {
export async function updatePreview(buildData, document, proxyLogger) {
const { challengeType } = buildData;
if (challengeType === challengeTypes.html) {
createMainFramer(document)(buildData);
await new Promise(resolve =>
createMainFramer(document, resolve, proxyLogger)(buildData)
);
} else {
throw new Error(`Cannot show preview for challenge type ${challengeType}`);
}

View File

@ -91,13 +91,7 @@ const buildProxyConsole = proxyLogger => ctx => {
};
const initTestFrame = frameReady => ctx => {
const contentLoaded = new Promise(resolve => {
if (ctx.document.readyState === 'loading') {
ctx.document.addEventListener('DOMContentLoaded', resolve);
} else {
resolve();
}
});
const contentLoaded = new Promise(resolve => waitForFrame(resolve)(ctx));
contentLoaded.then(async () => {
const { sources, loadEnzyme } = ctx;
// default for classic challenges
@ -111,6 +105,15 @@ const initTestFrame = frameReady => ctx => {
return ctx;
};
const waitForFrame = frameReady => ctx => {
if (ctx.document.readyState === 'loading') {
ctx.document.addEventListener('DOMContentLoaded', frameReady);
} else {
frameReady();
}
return ctx;
};
function writeToFrame(content, frame) {
frame.open();
frame.write(content);
@ -123,18 +126,17 @@ const writeContentToFrame = ctx => {
return ctx;
};
export const createMainFramer = document =>
flow(
createFrame(document, mainId),
mountFrame(document),
writeContentToFrame
);
export const createMainFramer = (document, frameReady, proxyConsole) =>
createFramer(document, frameReady, proxyConsole, mainId, waitForFrame);
export const createTestFramer = (document, frameReady, proxyConsole) =>
createFramer(document, frameReady, proxyConsole, testId, initTestFrame);
const createFramer = (document, frameReady, proxyConsole, id, init) =>
flow(
createFrame(document, testId),
createFrame(document, id),
mountFrame(document),
writeContentToFrame,
buildProxyConsole(proxyConsole),
initTestFrame(frameReady)
init(frameReady)
);