mirror of
				https://github.com/dgtlmoon/changedetection.io.git
				synced 2025-10-31 14:47:21 +00:00 
			
		
		
		
	Compare commits
	
		
			1 Commits
		
	
	
		
			0.50.26
			...
			visualsele
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | b629276ab9 | 
| @@ -13,6 +13,8 @@ urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) | ||||
| # Some common stuff here that can be moved to a base class | ||||
| # (set_proxy_from_list) | ||||
| class perform_site_check(): | ||||
|     screenshot = None | ||||
|     xpath_data = None | ||||
|  | ||||
|     def __init__(self, *args, datastore, **kwargs): | ||||
|         super().__init__(*args, **kwargs) | ||||
| @@ -127,6 +129,9 @@ class perform_site_check(): | ||||
|         fetcher.run(url, timeout, request_headers, request_body, request_method, ignore_status_codes, watch['css_filter']) | ||||
|         fetcher.quit() | ||||
|  | ||||
|         self.screenshot = fetcher.screenshot | ||||
|         self.xpath_data = fetcher.xpath_data | ||||
|  | ||||
|         # Fetching complete, now filters | ||||
|         # @todo move to class / maybe inside of fetcher abstract base? | ||||
|  | ||||
| @@ -312,4 +317,4 @@ class perform_site_check(): | ||||
|         if not watch.get('previous_md5'): | ||||
|             watch['previous_md5'] = fetched_md5 | ||||
|  | ||||
|         return changed_detected, update_obj, text_content_before_ignored_filter, fetcher.screenshot, fetcher.xpath_data | ||||
|         return changed_detected, update_obj, text_content_before_ignored_filter | ||||
|   | ||||
| @@ -38,13 +38,14 @@ docker kill $$-test_selenium | ||||
|  | ||||
| echo "TESTING WEBDRIVER FETCH > PLAYWRIGHT/BROWSERLESS..." | ||||
| # Not all platforms support playwright (not ARM/rPI), so it's not packaged in requirements.txt | ||||
| pip3 install playwright~=1.22 | ||||
| pip3 install playwright~=1.24 | ||||
| docker run -d --name $$-test_browserless -e "DEFAULT_LAUNCH_ARGS=[\"--window-size=1920,1080\"]" --rm  -p 3000:3000  --shm-size="2g"  browserless/chrome:1.53-chrome-stable | ||||
| # takes a while to spin up | ||||
| sleep 5 | ||||
| export PLAYWRIGHT_DRIVER_URL=ws://127.0.0.1:3000 | ||||
| pytest tests/fetchers/test_content.py | ||||
| pytest tests/test_errorhandling.py | ||||
| pytest tests/visualselector/test_fetch_data.py | ||||
|  | ||||
| unset PLAYWRIGHT_DRIVER_URL | ||||
| docker kill $$-test_browserless | ||||
| @@ -2,7 +2,7 @@ | ||||
|  | ||||
| import time | ||||
| from flask import url_for | ||||
| from ..util import live_server_setup | ||||
| from ..util import live_server_setup, wait_for_all_checks | ||||
| import logging | ||||
|  | ||||
|  | ||||
| @@ -29,14 +29,8 @@ def test_fetch_webdriver_content(client, live_server): | ||||
|  | ||||
|     assert b"1 Imported" in res.data | ||||
|     time.sleep(3) | ||||
|     attempt = 0 | ||||
|     while attempt < 20: | ||||
|         res = client.get(url_for("index")) | ||||
|         if not b'Checking now' in res.data: | ||||
|             break | ||||
|         logging.getLogger().info("Waiting for check to not say 'Checking now'..") | ||||
|         time.sleep(3) | ||||
|         attempt += 1 | ||||
|  | ||||
|     wait_for_all_checks(client) | ||||
|  | ||||
|  | ||||
|     res = client.get( | ||||
|   | ||||
| @@ -2,6 +2,8 @@ | ||||
|  | ||||
| from flask import make_response, request | ||||
| from flask import url_for | ||||
| import logging | ||||
| import time | ||||
|  | ||||
| def set_original_response(): | ||||
|     test_return_data = """<html> | ||||
| @@ -68,6 +70,31 @@ def extract_api_key_from_UI(client): | ||||
|     api_key = m.group(1) | ||||
|     return api_key.strip() | ||||
|  | ||||
|  | ||||
| # kinda funky, but works for now | ||||
| def extract_UUID_from_client(client): | ||||
|     import re | ||||
|     res = client.get( | ||||
|         url_for("index"), | ||||
|     ) | ||||
|     # <span id="api-key">{{api_key}}</span> | ||||
|  | ||||
|     m = re.search('edit/(.+?)"', str(res.data)) | ||||
|     uuid = m.group(1) | ||||
|     return uuid.strip() | ||||
|  | ||||
| def wait_for_all_checks(client): | ||||
|     # Loop waiting until done.. | ||||
|     attempt=0 | ||||
|     while attempt < 60: | ||||
|         time.sleep(1) | ||||
|         res = client.get(url_for("index")) | ||||
|         if not b'Checking now' in res.data: | ||||
|             break | ||||
|         logging.getLogger().info("Waiting for watch-list to not say 'Checking now'.. {}".format(attempt)) | ||||
|  | ||||
|         attempt += 1 | ||||
|  | ||||
| def live_server_setup(live_server): | ||||
|  | ||||
|     @live_server.app.route('/test-endpoint') | ||||
| @@ -133,3 +160,4 @@ def live_server_setup(live_server): | ||||
|         return ret | ||||
|  | ||||
|     live_server.start() | ||||
|  | ||||
|   | ||||
							
								
								
									
										2
									
								
								changedetectionio/tests/visualselector/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								changedetectionio/tests/visualselector/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| """Tests for the app.""" | ||||
|  | ||||
							
								
								
									
										3
									
								
								changedetectionio/tests/visualselector/conftest.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								changedetectionio/tests/visualselector/conftest.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| #!/usr/bin/python3 | ||||
|  | ||||
| from .. import conftest | ||||
							
								
								
									
										35
									
								
								changedetectionio/tests/visualselector/test_fetch_data.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								changedetectionio/tests/visualselector/test_fetch_data.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| #!/usr/bin/python3 | ||||
|  | ||||
| import time | ||||
| from flask import url_for | ||||
| from ..util import live_server_setup, wait_for_all_checks, extract_UUID_from_client | ||||
|  | ||||
| # Add a site in paused mode, add an invalid filter, we should still have visual selector data ready | ||||
| def test_visual_selector_content_ready(client, live_server): | ||||
|     import os | ||||
|  | ||||
|     assert os.getenv('PLAYWRIGHT_DRIVER_URL'), "Needs PLAYWRIGHT_DRIVER_URL set for this test" | ||||
|     live_server_setup(live_server) | ||||
|     time.sleep(1) | ||||
|  | ||||
|     # Add our URL to the import page, maybe better to use something we control? | ||||
|     # We use an external URL because the docker container is too difficult to setup to connect back to the pytest socket | ||||
|     test_url = 'https://news.ycombinator.com' | ||||
|     res = client.post( | ||||
|         url_for("form_quick_watch_add"), | ||||
|         data={"url": test_url, "tag": '', 'edit_and_watch_submit_button': 'Edit > Watch'}, | ||||
|         follow_redirects=True | ||||
|     ) | ||||
|     assert b"Watch added in Paused state, saving will unpause" in res.data | ||||
|  | ||||
|     res = client.post( | ||||
|         url_for("edit_page", uuid="first", unpause_on_save=1), | ||||
|         data={"css_filter": ".does-not-exist", "url": test_url, "tag": "", "headers": "", 'fetch_backend': "html_webdriver"}, | ||||
|         follow_redirects=True | ||||
|     ) | ||||
|     assert b"unpaused" in res.data | ||||
|     time.sleep(1) | ||||
|     wait_for_all_checks(client) | ||||
|     uuid = extract_UUID_from_client(client) | ||||
|     assert os.path.isfile(os.path.join('test-datastore', uuid, 'last-screenshot.png')), "last-screenshot.png should exist" | ||||
|     assert os.path.isfile(os.path.join('test-datastore', uuid, 'elements.json')), "xpath elements.json data should exist" | ||||
| @@ -142,7 +142,7 @@ class update_worker(threading.Thread): | ||||
|                     now = time.time() | ||||
|  | ||||
|                     try: | ||||
|                         changed_detected, update_obj, contents, screenshot, xpath_data = update_handler.run(uuid) | ||||
|                         changed_detected, update_obj, contents = update_handler.run(uuid) | ||||
|                         # Re #342 | ||||
|                         # In Python 3, all strings are sequences of Unicode characters. There is a bytes type that holds raw bytes. | ||||
|                         # We then convert/.decode('utf-8') for the notification etc | ||||
| @@ -222,6 +222,7 @@ class update_worker(threading.Thread): | ||||
|                         self.datastore.update_watch(uuid=uuid, update_obj={'last_error': err_text, | ||||
|                                                                            'last_check_status': e.status_code}) | ||||
|                     except content_fetcher.PageUnloadable as e: | ||||
|                         # @todo connection-refused ? | ||||
|                         err_text = "Page request from server didnt respond correctly" | ||||
|                         if e.screenshot: | ||||
|                             self.datastore.save_screenshot(watch_uuid=uuid, screenshot=e.screenshot, as_error=True) | ||||
| @@ -280,10 +281,10 @@ class update_worker(threading.Thread): | ||||
|                                                                        'last_checked': round(time.time())}) | ||||
|  | ||||
|                     # Always save the screenshot if it's available | ||||
|                     if screenshot: | ||||
|                         self.datastore.save_screenshot(watch_uuid=uuid, screenshot=screenshot) | ||||
|                     if xpath_data: | ||||
|                         self.datastore.save_xpath_data(watch_uuid=uuid, data=xpath_data) | ||||
|                     if update_handler.screenshot: | ||||
|                         self.datastore.save_screenshot(watch_uuid=uuid, screenshot=update_handler.screenshot) | ||||
|                     if update_handler.xpath_data: | ||||
|                         self.datastore.save_xpath_data(watch_uuid=uuid, data=update_handler.xpath_data) | ||||
|  | ||||
|  | ||||
|                 self.current_uuid = None  # Done | ||||
|   | ||||
		Reference in New Issue
	
	Block a user