Repository: psychopy/psychopy

Issue:
Routines run only once in Online Experiment
I had a trouble that routines in a loop run only once on Pavlovia.  Here is a simple example of this problem.  

https://gitlab.pavlovia.org/hsogo/kbtest
(created by the latest main branch of PsychoPy, on Windows 10 and Python 3.6.1)

I ran this project on local debugger (FireFox 81.0.2 win10 x64) and found that status of components were set to "FINISHED" at the end of the first iteration and not reset before starting next iteration.  I noticed that _if statement_ was output twice at the end of `trialRoutineBegin() ` and I suspect something is wrong here. 

```
var t;
var frameN;
var _key_resp_allKeys;
var trialComponents;
function trialRoutineBegin(snapshot) {
  return function () {
    //------Prepare to start Routine 'trial'-------
    t = 0;
    trialClock.reset(); // clock
    frameN = -1;
    // update component parameters for each repeat
    key_resp.keys = undefined;
    key_resp.rt = undefined;
    _key_resp_allKeys = [];
    // keep track of which components have finished
    trialComponents = [];
    trialComponents.push(key_resp);
    trialComponents.push(text);
    // check if the Routine should terminate
    if (!continueRoutine) {  // a component has requested a forced-end of Routine
      return Scheduler.Event.NEXT;
    }
    // check if the Routine should terminate
    if (!continueRoutine) {  // a component has requested a forced-end of Routine
      return Scheduler.Event.NEXT;
    }
  };
}
```



Discussion:
I compared code of 2020.2.4 and that of the master branch and found the cause.
New lines were inseted to psychopy/experiment/routine.py, but insertion point was wrong.  The new lines (line 306-312) must be inserted between line 314 and 315.

```
        if modular:
            code = ("\nfor (const thisComponent of %(name)sComponents)\n"
                    "  if ('status' in thisComponent)\n"
                    "    thisComponent.status = PsychoJS.Status.NOT_STARTED;\n"
                    "\nreturn Scheduler.Event.NEXT;\n" % self.params)
        else:
            code = ("\n%(name)sComponents.forEach( function(thisComponent) {\n"
                    "  if ('status' in thisComponent)\n"
                    "    thisComponent.status = PsychoJS.Status.NOT_STARTED;\n"
                    "   });\n"
                    "\nreturn Scheduler.Event.NEXT;\n" % self.params)
        # are we done yet?                                                       <------ line 306
        code = ("// check if the Routine should terminate\n"
                "if (!continueRoutine) {"
                "  // a component has requested a forced-end of Routine\n"
                "  return Scheduler.Event.NEXT;\n"
                "}\n")
        buff.writeIndentedLines(code)                                            <------ line 312

        buff.writeIndentedLines(code)                                            <------ line 314
```

Resolving patch:
diff --git a/psychopy/experiment/routine.py b/psychopy/experiment/routine.py
--- a/psychopy/experiment/routine.py
+++ b/psychopy/experiment/routine.py
@@ -295,14 +295,14 @@ def writeRoutineBeginCodeJS(self, buff, modular):
         if modular:
             code = ("\nfor (const thisComponent of %(name)sComponents)\n"
                     "  if ('status' in thisComponent)\n"
-                    "    thisComponent.status = PsychoJS.Status.NOT_STARTED;\n"
-                    "\nreturn Scheduler.Event.NEXT;\n" % self.params)
+                    "    thisComponent.status = PsychoJS.Status.NOT_STARTED;\n" % self.params)
         else:
             code = ("\n%(name)sComponents.forEach( function(thisComponent) {\n"
                     "  if ('status' in thisComponent)\n"
                     "    thisComponent.status = PsychoJS.Status.NOT_STARTED;\n"
-                    "   });\n"
-                    "\nreturn Scheduler.Event.NEXT;\n" % self.params)
+                    "   });\n" % self.params)
+        buff.writeIndentedLines(code)
+
         # are we done yet?
         code = ("// check if the Routine should terminate\n"
                 "if (!continueRoutine) {"
@@ -311,7 +311,6 @@ def writeRoutineBeginCodeJS(self, buff, modular):
                 "}\n")
         buff.writeIndentedLines(code)
 
-        buff.writeIndentedLines(code)
         buff.setIndentLevel(-1, relative=True)
         buff.writeIndentedLines("};\n")
         buff.setIndentLevel(-1, relative=True)


Test patch: