From 7269894a86047a3258066e76dad29b4ac40fcffd Mon Sep 17 00:00:00 2001 From: Oliver Eyton-Williams Date: Fri, 17 Jul 2020 21:03:23 +0200 Subject: [PATCH] refactor: test output -> arrays (#39178) --- .../src/templates/Challenges/classic/Show.js | 2 +- .../templates/Challenges/components/Output.js | 13 ++-- .../Challenges/projects/backend/Show.js | 4 +- .../src/templates/Challenges/redux/index.js | 22 +++---- .../integration/learn/challenges/output.js | 61 +++++++++++++++++++ 5 files changed, 84 insertions(+), 18 deletions(-) create mode 100644 cypress/integration/learn/challenges/output.js diff --git a/client/src/templates/Challenges/classic/Show.js b/client/src/templates/Challenges/classic/Show.js index 259b192bef..4f8f152a42 100644 --- a/client/src/templates/Challenges/classic/Show.js +++ b/client/src/templates/Challenges/classic/Show.js @@ -74,7 +74,7 @@ const propTypes = { }), initConsole: PropTypes.func.isRequired, initTests: PropTypes.func.isRequired, - output: PropTypes.string, + output: PropTypes.arrayOf(PropTypes.string), pageContext: PropTypes.shape({ challengeMeta: PropTypes.shape({ id: PropTypes.string, diff --git a/client/src/templates/Challenges/components/Output.js b/client/src/templates/Challenges/components/Output.js index 8600a4c21f..8f3aba840d 100644 --- a/client/src/templates/Challenges/components/Output.js +++ b/client/src/templates/Challenges/components/Output.js @@ -3,18 +3,23 @@ import PropTypes from 'prop-types'; import sanitizeHtml from 'sanitize-html'; import './output.css'; +import { isEmpty } from 'lodash'; const propTypes = { defaultOutput: PropTypes.string, - output: PropTypes.string + output: PropTypes.arrayOf(PropTypes.string) }; class Output extends Component { render() { const { output, defaultOutput } = this.props; - const message = sanitizeHtml(output ? output : defaultOutput, { - allowedTags: ['b', 'i', 'em', 'strong', 'code', 'wbr'] - }); + console.log('output', output); + const message = sanitizeHtml( + !isEmpty(output) ? output.join('\n') : defaultOutput, + { + allowedTags: ['b', 'i', 'em', 'strong', 'code', 'wbr'] + } + ); return (
 state[ns].canFocusEditor;
 export const inAccessibilityModeSelector = state =>
   state[ns].inAccessibilityMode;
 
-const MAX_LOGS_SIZE = 64 * 1024;
-
 export const reducer = handleActions(
   {
     [types.createFiles]: (state, { payload }) => ({
@@ -275,25 +275,25 @@ export const reducer = handleActions(
 
     [types.initConsole]: (state, { payload }) => ({
       ...state,
-      consoleOut: payload
+      consoleOut: payload ? [payload] : []
     }),
     [types.updateConsole]: (state, { payload }) => ({
       ...state,
-      consoleOut: state.consoleOut + '\n' + payload
+      consoleOut: state.consoleOut.concat(payload)
     }),
     [types.initLogs]: state => ({
       ...state,
-      logsOut: ''
+      logsOut: []
     }),
     [types.updateLogs]: (state, { payload }) => ({
       ...state,
-      logsOut: (state.logsOut + '\n' + payload).slice(-MAX_LOGS_SIZE)
+      logsOut: state.logsOut.concat(payload)
     }),
     [types.logsToConsole]: (state, { payload }) => ({
       ...state,
-      consoleOut:
-        state.consoleOut +
-        (state.logsOut ? '\n' + payload + '\n' + state.logsOut : '')
+      consoleOut: isEmpty(state.logsOut)
+        ? state.consoleOut
+        : state.consoleOut.concat(payload, state.logsOut)
     }),
     [types.updateChallengeMeta]: (state, { payload }) => ({
       ...state,
@@ -321,7 +321,7 @@ export const reducer = handleActions(
         text,
         testString
       })),
-      consoleOut: ''
+      consoleOut: []
     }),
     [types.updateSolutionFormValues]: (state, { payload }) => ({
       ...state,
diff --git a/cypress/integration/learn/challenges/output.js b/cypress/integration/learn/challenges/output.js
new file mode 100644
index 0000000000..03fb0934ca
--- /dev/null
+++ b/cypress/integration/learn/challenges/output.js
@@ -0,0 +1,61 @@
+/* global cy */
+
+const selectors = {
+  defaultOutput: '.output-text',
+  hotkeys: '.default-layout > div',
+  runTestsButton: 'button:contains("Run the Tests")'
+};
+
+const locations = {
+  index:
+    '/learn/responsive-web-design/basic-html-and-html5/' +
+    'say-hello-to-html-elements'
+};
+
+const defaultOutput = `
+/**
+* Your test output will go here.
+*/`;
+
+const runningOutput = '// running tests';
+const finishedOutput = '// tests completed';
+
+describe('Classic challenge', function() {
+  it('renders', () => {
+    cy.visit(locations.index);
+
+    cy.title().should(
+      'eq',
+      'Learn Basic HTML and HTML5: Say Hello to HTML Elements |' +
+        ' freeCodeCamp.org'
+    );
+  });
+
+  it('renders the default output text', () => {
+    cy.visit(locations.index);
+    cy.get(selectors.defaultOutput).contains(defaultOutput);
+  });
+
+  it('shows test output when the tests are run', () => {
+    cy.visit(locations.index);
+    cy.get(selectors.runTestsButton)
+      .click()
+      .then(() => {
+        cy.get(selectors.defaultOutput)
+          .contains(runningOutput)
+          .contains(finishedOutput);
+      });
+  });
+
+  it('shows test output when the tests are triggered by the keyboard', () => {
+    cy.visit(locations.index);
+    cy.get(selectors.hotkeys)
+      .focus()
+      .type('{ctrl}{enter}')
+      .then(() => {
+        cy.get(selectors.defaultOutput)
+          .contains(runningOutput)
+          .contains(finishedOutput);
+      });
+  });
+});