Repository: biglocalnews/court-scraper (language: python)

Issue:
CI invocations for non-captcha tests?
> Related to #149

@palewire raised the below questions about test invocations in a CI and non-CI context in #147

> How would we handle the command-line options to create cases where:
> A) Only CAPTCHA tests should be run
> B) Only login-only based "slow" webtests should be run
> C) All webtests, regardless of login method, should be run

For *A*, `pyest --runslow -m captcha` should work. This would not be run on CI, but is intended for manual runs by core devs and contributors (ideally prior to merging to `master`).

For *B* and *C*, one option would be to add yet another pyest marker such as `noncaptcha` to all webtests without a captcha.

We could then selectively target tests as below:

```bash
# Run all slow tests except for CAPTCHA-based
# For use on CI
pytest --runslow -m noncaptcha 

# For local dev
# Run all tests
pytest --runslow  

# Run only CAPTCHA
pytest --runslow -m captcha 
```

The above assumes that we devise a solution for passing in login credentials via environment variables, per #149.
Action for slow tests
This new workflow will run the slow and web tests when:
1. A pull request is submitted
2. Once per week on a cron
3. You manually click a button here on GitHub


Discussion / hints:

Fix patch:
diff --git a/Makefile b/Makefile
index 1997f6e..f9bf0fb 100644
--- a/Makefile
+++ b/Makefile
@@ -24,6 +24,7 @@ BROWSER := python -c "$$BROWSER_PYSCRIPT"
 
 PIPENV := pipenv run
 PYTHON := $(PYTHON) python -W ignore
+PYTEST := $(PIPENV) py.test
 
 define python
     @echo "🐍🤖 $(OBJ_COLOR)Executing Python script $(1)$(NO_COLOR)\r";
@@ -85,12 +86,24 @@ lint: ## check style with flake8
 	@$(PIPENV) flake8 court_scraper tests
 
 
-test: ## run tests quickly with the default Python
-	@$(PIPENV) py.test
+test: ## run all quick tests with the default Python
+	@$(PYTEST)
 
 
-test-all: ## run tests on every Python version with tox
-	@$(PIPENV) tox -p auto
+test-tox: ## run all quick tests on all Python versions
+	@$(PYTEST) tox -p auto
+
+
+test-slow: ## run all slow tests
+	@$(PYTEST) --runslow
+
+
+test-slow-nocaptcha: ## run only slow tests that do not require captcha
+	@$(PYTEST) --runslow -m nocaptcha
+
+
+test-slow-captcha: ## run only slow tests that do not require captcha
+	@$(PYTEST) --runslow -m captcha
 
 
 coverage: ## check code coverage quickly with the default Python
@@ -148,9 +161,22 @@ install: clean ## install the package to the active Python's site-packages
 
 
 # Mark all the commands that don't have a target
-.PHONY: clean \
+.PHONY: help \
+        clean \
         clean-test \
         clean-pyc \
         clean-build \
+        lint \
+        test \
+        test-tox \
+        test-slow \
+        test-slow-nocaptcha \
+        test-slow-captcha \
+        coverage \
         docs \
-        help
+        servedocs \
+        check-release \
+        test-release \
+        release \
+        dist \
+        install


Test patch:
diff --git a/tests/conftest.py b/tests/conftest.py
index 3127105..1d8b5d3 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -56,6 +56,7 @@ def pytest_configure(config):
     config.addinivalue_line("markers", "slow: mark test as slow to run")
     config.addinivalue_line("markers", "webtest: mark test as hitting live websites")
     config.addinivalue_line("markers", "captcha: mark test as requiring captcha")
+    config.addinivalue_line("markers", "nocaptcha: mark test as not requiring captcha")
 
 
 def pytest_collection_modifyitems(config, items):
diff --git a/tests/platforms/test_odyssey_site.py b/tests/platforms/test_odyssey_site.py
index 4bb2821..e727050 100644
--- a/tests/platforms/test_odyssey_site.py
+++ b/tests/platforms/test_odyssey_site.py
@@ -40,6 +40,7 @@ def test_login(webdriver_mock, login_page_mock):
 )
 @pytest.mark.slow
 @pytest.mark.webtest
+@pytest.mark.nocaptcha
 def test_search(test_input, headless, live_configs, court_scraper_dir):
     auth = live_configs['ga_dekalb']
     username = auth['username']
@@ -65,6 +66,7 @@ def test_search(test_input, headless, live_configs, court_scraper_dir):
 )
 @pytest.mark.slow
 @pytest.mark.webtest
+@pytest.mark.nocaptcha
 def test_search_nologin_no_captcha(test_input, headless, court_scraper_dir):
     place_id, url, case_ids = test_input
     site = OdysseySite(place_id, url=url, download_dir=court_scraper_dir, headless=headless)
@@ -84,6 +86,7 @@ def test_search_nologin_no_captcha(test_input, headless, court_scraper_dir):
 )
 @pytest.mark.slow
 @pytest.mark.webtest
+@pytest.mark.nocaptcha
 def test_search_nologin_no_captcha_noresults(test_input, headless, court_scraper_dir):
     place_id, url, case_ids = test_input
     site = OdysseySite(place_id, url=url, download_dir=court_scraper_dir, headless=headless)
@@ -103,6 +106,7 @@ def test_search_nologin_no_captcha_noresults(test_input, headless, court_scraper
 )
 @pytest.mark.slow
 @pytest.mark.webtest
+@pytest.mark.nocaptcha
 def test_scrape_case_details(test_input, headless, live_configs, court_scraper_dir):
     "should support optional scraping of case details"
     auth = live_configs['ga_dekalb']
@@ -129,6 +133,7 @@ def test_scrape_case_details(test_input, headless, live_configs, court_scraper_d
 )
 @pytest.mark.slow
 @pytest.mark.webtest
+@pytest.mark.nocaptcha
 def test_maximize_displayed_results(test_input, headless, court_scraper_dir):
     "should automatically maximize the number of results displayed on results page"
     place_id, url, case_ids = test_input
@@ -149,6 +154,7 @@ def test_maximize_displayed_results(test_input, headless, court_scraper_dir):
 )
 @pytest.mark.slow
 @pytest.mark.webtest
+@pytest.mark.nocaptcha
 def test_malformed_result_listing(test_input, headless, live_configs, court_scraper_dir):
     "should handle result listings that have an extra leading blank cell"
     auth = live_configs['ga_dekalb']
diff --git a/tests/test_cli.py b/tests/test_cli.py
index f06f510..76a4171 100644
--- a/tests/test_cli.py
+++ b/tests/test_cli.py
@@ -16,6 +16,7 @@
 
 @pytest.mark.slow
 @pytest.mark.webtest
+@pytest.mark.captcha
 @pytest.mark.usefixtures('set_env', 'create_scraper_dir', 'create_config')
 def test_integration_wicourts(court_scraper_dir, config_path, headless):
     # Add captcha key to test config file
@@ -62,6 +63,7 @@ def test_integration_oscn(court_scraper_dir):
 
 @pytest.mark.slow
 @pytest.mark.webtest
+@pytest.mark.nocaptcha
 @pytest.mark.usefixtures('set_env', 'create_scraper_dir', 'create_config')
 def test_integration_odyssey(court_scraper_dir):
     # Using a non-login and non-Captcha site
diff --git a/tests/test_site.py b/tests/test_site.py
index 3893cd2..de06c44 100644
--- a/tests/test_site.py
+++ b/tests/test_site.py
@@ -11,6 +11,7 @@
     ("wi_milwaukee", "Site"),
 ])
 @pytest.mark.slow
+@pytest.mark.nocaptcha
 @pytest.mark.usefixtures('set_env', 'create_scraper_dir', 'create_config')
 def test_site(place_id, site_class):
     site = Site(place_id)
@@ -19,6 +20,7 @@ def test_site(place_id, site_class):
 
 @pytest.mark.webtest
 @pytest.mark.slow
+@pytest.mark.nocaptcha
 @pytest.mark.usefixtures('create_scraper_dir', 'create_config')
 def test_site_odyssey(headless):
     site = Site('ca_napa', headless=headless)
@@ -29,6 +31,7 @@ def test_site_odyssey(headless):
 
 @pytest.mark.webtest
 @pytest.mark.slow
+@pytest.mark.captcha
 @pytest.mark.usefixtures('set_env', 'create_scraper_dir', 'create_config')
 def test_site_wicourts(config_path, headless):
     # Add captcha key to test config file in order to