Repository: oppia/oppia

Issue:
Add checking frontend coverage in pre_push hook.
By now, the frontend coverage is not being checked on the pre_push hook, this is slowing down the process on merging PRs. If any coverage changes are made, it should be fixed before pushing it to the repository.



Discussion:

Resolving patch:
diff --git a/scripts/pre_push_hook.py b/scripts/pre_push_hook.py
--- a/scripts/pre_push_hook.py
+++ b/scripts/pre_push_hook.py
@@ -61,8 +61,10 @@
     OPPIA_PARENT_DIR, 'oppia_tools', 'node-10.18.0', 'bin', 'npm')
 YARN_CMD = os.path.join(
     OPPIA_PARENT_DIR, 'oppia_tools', 'yarn-v1.22.0', 'bin', 'yarn')
-FRONTEND_TEST_SCRIPT = 'run_frontend_tests'
-TRAVIS_CI_PROTRACTOR_CHECK_SCRIPT = 'check_e2e_tests_are_captured_in_ci'
+FRONTEND_TEST_CMDS = [
+    PYTHON_CMD, '-m', 'scripts.run_frontend_tests', '--check_coverage']
+TRAVIS_CI_PROTRACTOR_CHECK_CMDS = [
+    PYTHON_CMD, '-m', 'scripts.check_e2e_tests_are_captured_in_ci']
 GIT_IS_DIRTY_CMD = 'git status --porcelain --untracked-files=no'
 
 
@@ -272,12 +274,16 @@ def start_linter(files):
     return task.returncode
 
 
-def start_python_script(scriptname):
-    """Runs the 'start.py' script and returns the returncode of the task."""
-    cmd = [
-        'python', '-m',
-        os.path.join('scripts', scriptname).replace('/', '.')]
-    task = subprocess.Popen(cmd)
+def run_script_and_get_returncode(cmd_list):
+    """Runs script and returns the returncode of the task.
+
+    Args:
+        cmd_list: list(str). The cmd list containing the command to be run.
+
+    Returns:
+        int. The return code from the task executed.
+    """
+    task = subprocess.Popen(cmd_list)
     task.communicate()
     task.wait()
     return task.returncode
@@ -393,14 +399,15 @@ def main(args=None):
             frontend_status = 0
             travis_ci_check_status = 0
             if does_diff_include_js_or_ts_files(files_to_lint):
-                frontend_status = start_python_script(FRONTEND_TEST_SCRIPT)
+                frontend_status = run_script_and_get_returncode(
+                    FRONTEND_TEST_CMDS)
             if frontend_status != 0:
                 python_utils.PRINT(
                     'Push aborted due to failing frontend tests.')
                 sys.exit(1)
             if does_diff_include_travis_yml_or_js_files(files_to_lint):
-                travis_ci_check_status = start_python_script(
-                    TRAVIS_CI_PROTRACTOR_CHECK_SCRIPT)
+                travis_ci_check_status = run_script_and_get_returncode(
+                    TRAVIS_CI_PROTRACTOR_CHECK_CMDS)
             if travis_ci_check_status != 0:
                 python_utils.PRINT(
                     'Push aborted due to failing e2e test configuration check.')


Test patch:
diff --git a/scripts/pre_push_hook_test.py b/scripts/pre_push_hook_test.py
--- a/scripts/pre_push_hook_test.py
+++ b/scripts/pre_push_hook_test.py
@@ -329,9 +329,10 @@ def test_start_linter(self):
         with self.popen_swap:
             self.assertEqual(pre_push_hook.start_linter(['files']), 0)
 
-    def test_start_python_script(self):
+    def test_run_script_and_get_returncode(self):
         with self.popen_swap:
-            self.assertEqual(pre_push_hook.start_python_script('script'), 0)
+            self.assertEqual(
+                pre_push_hook.run_script_and_get_returncode('script'), 0)
 
     def test_has_uncommitted_files(self):
         def mock_check_output(unused_cmd_tokens):
@@ -499,14 +500,15 @@ def test_lint_failure(self):
 
     def test_frontend_test_failure(self):
         self.does_diff_include_js_or_ts_files = True
-        def mock_start_python_script(unused_script):
+        def mock_run_script_and_get_returncode(unused_script):
             return 1
-        start_python_script_swap = self.swap(
-            pre_push_hook, 'start_python_script', mock_start_python_script)
+        run_script_and_get_returncode_swap = self.swap(
+            pre_push_hook, 'run_script_and_get_returncode',
+            mock_run_script_and_get_returncode)
         with self.get_remote_name_swap, self.get_refs_swap, self.print_swap:
             with self.collect_files_swap, self.uncommitted_files_swap:
                 with self.check_output_swap, self.start_linter_swap:
-                    with self.js_or_ts_swap, start_python_script_swap:
+                    with self.js_or_ts_swap, run_script_and_get_returncode_swap:
                         with self.assertRaises(SystemExit):
                             pre_push_hook.main(args=[])
         self.assertTrue(
@@ -515,14 +517,15 @@ def mock_start_python_script(unused_script):
     def test_invalid_travis_e2e_test_suites_failure(self):
         self.does_diff_include_travis_yml_or_js_files = True
 
-        def mock_start_python_script(unused_script):
+        def mock_run_script_and_get_returncode(unused_script):
             return 1
-        start_python_script_swap = self.swap(
-            pre_push_hook, 'start_python_script', mock_start_python_script)
+        run_script_and_get_returncode_swap = self.swap(
+            pre_push_hook, 'run_script_and_get_returncode',
+            mock_run_script_and_get_returncode)
         with self.get_remote_name_swap, self.get_refs_swap, self.print_swap:
             with self.collect_files_swap, self.uncommitted_files_swap:
                 with self.check_output_swap, self.start_linter_swap:
-                    with start_python_script_swap:
+                    with run_script_and_get_returncode_swap:
                         with self.travis_yml_or_js_files_swap:
                             with self.assertRaises(SystemExit):
                                 pre_push_hook.main(args=[])