From 5d9dccb37f4e695775a3ee3b22858667941dbd46 Mon Sep 17 00:00:00 2001 From: Oliver Eyton-Williams Date: Tue, 9 May 2023 19:45:08 +0200 Subject: [PATCH] test: unlock when syntax error fixed (#50325) * refactor: use data-cy for console output * test(client): unlock after fixing syntax errors --- .../Challenges/components/output.tsx | 1 + .../e2e/default/learn/challenge-hot-keys.ts | 9 +++--- .../e2e/default/learn/challenges/backend.ts | 2 +- .../default/learn/challenges/javascript.ts | 31 +++++++++++++++++++ .../e2e/default/learn/challenges/output.ts | 17 +++++----- cypress/support/selectors.ts | 3 +- 6 files changed, 48 insertions(+), 15 deletions(-) create mode 100644 cypress/e2e/default/learn/challenges/javascript.ts diff --git a/client/src/templates/Challenges/components/output.tsx b/client/src/templates/Challenges/components/output.tsx index 043c4b2051d..cd1cf0a187e 100644 --- a/client/src/templates/Challenges/components/output.tsx +++ b/client/src/templates/Challenges/components/output.tsx @@ -20,6 +20,7 @@ function Output({ defaultOutput, output }: OutputProps): JSX.Element { return (
 {
   it('should be possible to press ctrl enter to run the test', () => {
     cy.visit(links.classic1);
     cy.get(hotKeySelectors.instructions).click().type('{ctrl}{enter}');
-    cy.get(hotKeySelectors.console).contains('// running tests');
+    cy.get(selectors.dataCy.outputText).contains('// running tests');
   });
 
   it('should be possible to go to navigation view by pressing escape', () => {
@@ -100,7 +101,7 @@ describe('The hotkeys should work correctly', () => {
   it('it should be possible to focus on the instructions by pressing r', () => {
     cy.visit(links.classic1);
     cy.get(hotKeySelectors.editorContainer).type('{esc}');
-    cy.get(hotKeySelectors.console).click().type('r');
+    cy.get(selectors.dataCy.outputText).click().type('r');
     cy.get(hotKeySelectors.instructionsPanel).should('have.focus');
   });
 });
diff --git a/cypress/e2e/default/learn/challenges/backend.ts b/cypress/e2e/default/learn/challenges/backend.ts
index 75333948cfb..7e5daa91333 100644
--- a/cypress/e2e/default/learn/challenges/backend.ts
+++ b/cypress/e2e/default/learn/challenges/backend.ts
@@ -27,7 +27,7 @@ describe('Backend challenge', function () {
       .type('https://example.com')
       .type('{enter}')
       .then(() => {
-        cy.get(selectors.class.outputText)
+        cy.get(selectors.dataCy.outputText)
           .contains(runningOutput)
           .contains(finishedOutput);
         cy.contains(unhandledErrorMessage).should('not.exist');
diff --git a/cypress/e2e/default/learn/challenges/javascript.ts b/cypress/e2e/default/learn/challenges/javascript.ts
new file mode 100644
index 00000000000..72e40a937b4
--- /dev/null
+++ b/cypress/e2e/default/learn/challenges/javascript.ts
@@ -0,0 +1,31 @@
+import { selectors } from '../../../../support/selectors';
+
+describe('JavaScript challenges', function () {
+  const location =
+    '/learn/javascript-algorithms-and-data-structures/basic-javascript/comment-your-javascript-code';
+
+  before(() => {
+    cy.visit(location);
+  });
+
+  it('locks and unlocks code checks when a user makes and fixes an error', () => {
+    const workingOutput = 'Your test output will go here';
+    // We're using this as a proxy for the lock, since we don't currently
+    // disable the button when there's a syntax error (the checks will just not
+    // be triggered)
+    const brokenOutput = 'SyntaxError: unknown: Unexpected token';
+    // Unlocked
+    cy.get(selectors.dataCy.outputText).as('output').contains(workingOutput);
+    // Lock with a syntax error
+    cy.get(selectors.class.reactMonacoEditor)
+      .as('editor')
+      .click()
+      .focused()
+      .type(`{movetoend}var`);
+    cy.get('@output').contains(brokenOutput);
+
+    // Unlock by fixing the error.
+    cy.get('@editor').click().focused().type(`{movetoend} x = 1;`);
+    cy.get('@output').contains(workingOutput);
+  });
+});
diff --git a/cypress/e2e/default/learn/challenges/output.ts b/cypress/e2e/default/learn/challenges/output.ts
index 3cc86a1087c..3077143f5a1 100644
--- a/cypress/e2e/default/learn/challenges/output.ts
+++ b/cypress/e2e/default/learn/challenges/output.ts
@@ -1,5 +1,6 @@
+import { selectors } from '../../../../support/selectors';
+
 const outputSelectors = {
-  defaultOutput: '.output-text',
   editor: 'div.monaco-editor',
   hotkeys: '.default-layout > div',
   runTestsButton: 'button:contains("Run the Tests")'
@@ -35,7 +36,7 @@ describe('Classic challenge', function () {
       'eq',
       'Basic HTML and HTML5: Say Hello to HTML Elements |' + ' freeCodeCamp.org'
     );
-    cy.get(outputSelectors.defaultOutput).contains(defaultOutput);
+    cy.get(selectors.dataCy.outputText).contains(defaultOutput);
   });
 
   it('shows test output when the tests are run', () => {
@@ -44,7 +45,7 @@ describe('Classic challenge', function () {
     cy.get(outputSelectors.runTestsButton)
       .click()
       .then(() => {
-        cy.get(outputSelectors.defaultOutput)
+        cy.get(selectors.dataCy.outputText)
           .contains(runningOutput)
           .contains(finishedOutput);
       });
@@ -54,7 +55,7 @@ describe('Classic challenge', function () {
     focusEditor()
       .type('{ctrl}{enter}')
       .then(() => {
-        cy.get(outputSelectors.defaultOutput)
+        cy.get(selectors.dataCy.outputText)
           .contains(runningOutput)
           .contains(finishedOutput);
       });
@@ -71,12 +72,12 @@ describe('jQuery challenge', function () {
       'eq',
       'jQuery: Target HTML Elements with Selectors Using jQuery | freeCodeCamp.org'
     );
-    cy.get(outputSelectors.defaultOutput).contains(defaultOutput);
+    cy.get(selectors.dataCy.outputText).contains(defaultOutput);
   });
 
   it('should not show a reference error', () => {
     cy.wait(5000);
-    cy.get(outputSelectors.defaultOutput).should(
+    cy.get(selectors.dataCy.outputText).should(
       'not.contain',
       'ReferenceError: $ is not defined'
     );
@@ -93,7 +94,7 @@ describe('Custom output for JavaScript objects', function () {
     focusEditor().type(
       'const set = new Set();{enter}set.add(1);{enter}set.add("set");{enter}set.add(10);{enter}console.log(set);'
     );
-    cy.get(outputSelectors.defaultOutput).should(
+    cy.get(selectors.dataCy.outputText).should(
       'contain',
       'Set(3) {1, set, 10}'
     );
@@ -103,7 +104,7 @@ describe('Custom output for JavaScript objects', function () {
     focusEditor().type(
       'const map = new Map();{enter}map.set("first", 1);{enter}map.set("second", 2);{enter}map.set("other", "map");{enter}console.log(map);'
     );
-    cy.get(outputSelectors.defaultOutput).should(
+    cy.get(selectors.dataCy.outputText).should(
       'contain',
       'Map(3) {first => 1, second => 2, other => map})'
     );
diff --git a/cypress/support/selectors.ts b/cypress/support/selectors.ts
index 256faa80963..8eb3d7440bd 100644
--- a/cypress/support/selectors.ts
+++ b/cypress/support/selectors.ts
@@ -1,10 +1,9 @@
 export const selectors = {
   class: {
-    outputText: '.output-text',
     reactMonacoEditor: '.react-monaco-editor-container'
   },
   id: {},
-  data: {},
+  dataCy: { outputText: '[data-cy="output-text"]' },
   tag: {
     inputSolution: 'input[name="solution"]'
   }