From 00a1d25fbb06109beca400c965aba6270a6a6ac7 Mon Sep 17 00:00:00 2001 From: Valeriy Date: Sat, 12 Jan 2019 03:41:45 +0300 Subject: [PATCH] feat(learn): lazy load Enzyme in the test frame --- client/src/client/frame-runner.js | 17 +++++++++--- .../redux/execute-challenge-saga.js | 1 + .../src/templates/Challenges/utils/frame.js | 26 +++++-------------- client/webpack-frame-runner.js | 7 ++++- 4 files changed, 27 insertions(+), 24 deletions(-) diff --git a/client/src/client/frame-runner.js b/client/src/client/frame-runner.js index 6ae8776250..f2d3c2e94f 100644 --- a/client/src/client/frame-runner.js +++ b/client/src/client/frame-runner.js @@ -9,7 +9,10 @@ if (window.frameElement && window.frameElement.id === testId) { document.addEventListener('DOMContentLoaded', initTestFrame); } -function initTestFrame() { +// For tests in CI. +document.__initTestFrame = initTestFrame; + +async function initTestFrame() { const code = (document.__source || '').slice(0); if (!document.__getUserInput) { document.__getUserInput = () => code; @@ -38,8 +41,16 @@ function initTestFrame() { const assert = chai.assert; /* eslint-enable no-unused-vars */ - if (document.Enzyme) { - window.Enzyme = document.Enzyme; + let Enzyme; + if (document.__loadEnzyme) { + let Adapter16; + /* eslint-disable no-inline-comments */ + [{ default: Enzyme }, { default: Adapter16 }] = await Promise.all([ + import(/* webpackChunkName: "enzyme" */ 'enzyme'), + import(/* webpackChunkName: "enzyme-adapter" */ 'enzyme-adapter-react-16') + ]); + /* eslint-enable no-inline-comments */ + Enzyme.configure({ adapter: new Adapter16() }); } document.__runTest = async function runTests(testString) { diff --git a/client/src/templates/Challenges/redux/execute-challenge-saga.js b/client/src/templates/Challenges/redux/execute-challenge-saga.js index 41e03e0672..719715ac42 100644 --- a/client/src/templates/Challenges/redux/execute-challenge-saga.js +++ b/client/src/templates/Challenges/redux/execute-challenge-saga.js @@ -112,6 +112,7 @@ function* executeDOMChallengeSaga(proxyLogger) { const meta = yield select(challengeMetaSelector); const document = yield getContext('document'); const ctx = yield call(buildDOMChallenge, files, meta); + ctx.loadEnzyme = Object.keys(files).some(key => files[key].ext === 'jsx'); yield call(createTestFrame, document, ctx, proxyLogger); // wait for a code execution on a "ready" event in jQuery challenges yield delay(100); diff --git a/client/src/templates/Challenges/utils/frame.js b/client/src/templates/Challenges/utils/frame.js index 3402a5e393..c4fff6759b 100644 --- a/client/src/templates/Challenges/utils/frame.js +++ b/client/src/templates/Challenges/utils/frame.js @@ -1,7 +1,4 @@ import { toString, flow } from 'lodash'; -import { configure, shallow, mount } from 'enzyme'; -import Adapter16 from 'enzyme-adapter-react-16'; -import { setConfig } from 'react-hot-loader'; // we use two different frames to make them all essentially pure functions // main iframe is responsible rendering the preview and is where we proxy the @@ -33,17 +30,10 @@ const createHeader = (id = mainId) => ` export const runTestInTestFrame = async function(document, test, timeout) { const { contentDocument: frame } = document.getElementById(testId); - // Enable Stateless Functional Component. Otherwise, enzyme-adapter-react-16 - // does not work correctly. - setConfig({ pureSFC: true }); - try { - return await Promise.race([ - new Promise((_, reject) => setTimeout(() => reject('timeout'), timeout)), - frame.__runTest(test) - ]); - } finally { - setConfig({ pureSFC: false }); - } + return await Promise.race([ + new Promise((_, reject) => setTimeout(() => reject('timeout'), timeout)), + frame.__runTest(test) + ]); }; const createFrame = (document, id) => ctx => { @@ -83,18 +73,14 @@ const buildProxyConsole = proxyLogger => ctx => { }; const writeTestDepsToDocument = frameReady => ctx => { - const { sources } = ctx; - // add enzyme - // TODO: do programatically - // TODO: webpack lazyload this - configure({ adapter: new Adapter16() }); - ctx.document.Enzyme = { shallow, mount }; + const { sources, loadEnzyme } = ctx; // default for classic challenges // should not be used for modern ctx.document.__source = sources && 'index' in sources ? sources['index'] : ''; // provide the file name and get the original source ctx.document.__getUserInput = fileName => toString(sources[fileName]); ctx.document.__frameReady = frameReady; + ctx.document.__loadEnzyme = loadEnzyme; return ctx; }; diff --git a/client/webpack-frame-runner.js b/client/webpack-frame-runner.js index 16e5dc5b14..f16d8b0b47 100644 --- a/client/webpack-frame-runner.js +++ b/client/webpack-frame-runner.js @@ -11,6 +11,8 @@ module.exports = (env = {}) => { }, devtool: __DEV__ ? 'inline-source-map' : 'source-map', output: { + publicPath: '/js/', + chunkFilename: '[name].js', path: path.join(__dirname, './static/js') }, stats: { @@ -32,7 +34,10 @@ module.exports = (env = {}) => { { modules: false, targets: '> 0.25%, not dead' } ] ], - plugins: ['@babel/plugin-transform-runtime'] + plugins: [ + '@babel/plugin-transform-runtime', + '@babel/plugin-syntax-dynamic-import' + ] } } }