From a8b3918fca9fbc8e9f5a7f3539cd13e4a05096b0 Mon Sep 17 00:00:00 2001
From: dgtlmoon
Date: Mon, 10 Feb 2025 10:49:40 +0100
Subject: [PATCH 01/23] Browser Steps - Fixing 'Uncheck checkbox' #2958
---
changedetectionio/blueprint/browser_steps/browser_steps.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/changedetectionio/blueprint/browser_steps/browser_steps.py b/changedetectionio/blueprint/browser_steps/browser_steps.py
index b9765bacd..d4f3a9862 100644
--- a/changedetectionio/blueprint/browser_steps/browser_steps.py
+++ b/changedetectionio/blueprint/browser_steps/browser_steps.py
@@ -188,7 +188,7 @@ class steppable_browser_interface():
self.page.locator(selector).check(timeout=1000)
def action_uncheck_checkbox(self, selector, value):
- self.page.locator(selector, timeout=1000).uncheck(timeout=1000)
+ self.page.locator(selector).uncheck(timeout=1000)
# Responsible for maintaining a live 'context' with the chrome CDP
From 5d9380609cb6d180368bbd5045172e4df8369355 Mon Sep 17 00:00:00 2001
From: dgtlmoon
Date: Mon, 10 Feb 2025 10:56:44 +0100
Subject: [PATCH 02/23] Browser Steps - Increasing timeout for actions and
unifying timeout values
---
.../blueprint/browser_steps/browser_steps.py | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/changedetectionio/blueprint/browser_steps/browser_steps.py b/changedetectionio/blueprint/browser_steps/browser_steps.py
index d4f3a9862..d2141eb41 100644
--- a/changedetectionio/blueprint/browser_steps/browser_steps.py
+++ b/changedetectionio/blueprint/browser_steps/browser_steps.py
@@ -52,6 +52,8 @@ class steppable_browser_interface():
page = None
start_url = None
+ action_timeout = 10 * 1000
+
def __init__(self, start_url):
self.start_url = start_url
@@ -102,7 +104,7 @@ class steppable_browser_interface():
return
elem = self.page.get_by_text(value)
if elem.count():
- elem.first.click(delay=randint(200, 500), timeout=3000)
+ elem.first.click(delay=randint(200, 500), timeout=self.action_timeout)
def action_click_element_containing_text_if_exists(self, selector=None, value=''):
logger.debug("Clicking element containing text if exists")
@@ -111,7 +113,7 @@ class steppable_browser_interface():
elem = self.page.get_by_text(value)
logger.debug(f"Clicking element containing text - {elem.count()} elements found")
if elem.count():
- elem.first.click(delay=randint(200, 500), timeout=3000)
+ elem.first.click(delay=randint(200, 500), timeout=self.action_timeout)
else:
return
@@ -119,7 +121,7 @@ class steppable_browser_interface():
if not len(selector.strip()):
return
- self.page.fill(selector, value, timeout=10 * 1000)
+ self.page.fill(selector, value, timeout=self.action_timeout)
def action_execute_js(self, selector, value):
response = self.page.evaluate(value)
@@ -130,7 +132,7 @@ class steppable_browser_interface():
if not len(selector.strip()):
return
- self.page.click(selector=selector, timeout=30 * 1000, delay=randint(200, 500))
+ self.page.click(selector=selector, timeout=self.action_timeout + 20 * 1000, delay=randint(200, 500))
def action_click_element_if_exists(self, selector, value):
import playwright._impl._errors as _api_types
@@ -138,7 +140,7 @@ class steppable_browser_interface():
if not len(selector.strip()):
return
try:
- self.page.click(selector, timeout=10 * 1000, delay=randint(200, 500))
+ self.page.click(selector, timeout=self.action_timeout, delay=randint(200, 500))
except _api_types.TimeoutError as e:
return
except _api_types.Error as e:
@@ -185,10 +187,10 @@ class steppable_browser_interface():
self.page.keyboard.press("PageDown", delay=randint(200, 500))
def action_check_checkbox(self, selector, value):
- self.page.locator(selector).check(timeout=1000)
+ self.page.locator(selector).check(timeout=self.action_timeout)
def action_uncheck_checkbox(self, selector, value):
- self.page.locator(selector).uncheck(timeout=1000)
+ self.page.locator(selector).uncheck(timeout=self.action_timeout)
# Responsible for maintaining a live 'context' with the chrome CDP
From 82211eef820024e4f20d7d2206b922e6307ee1eb Mon Sep 17 00:00:00 2001
From: dgtlmoon
Date: Tue, 11 Feb 2025 11:15:13 +0100
Subject: [PATCH 03/23] Update settings.html
---
changedetectionio/templates/settings.html | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/changedetectionio/templates/settings.html b/changedetectionio/templates/settings.html
index 7a41a2625..e13bbe60c 100644
--- a/changedetectionio/templates/settings.html
+++ b/changedetectionio/templates/settings.html
@@ -280,9 +280,7 @@ nav
-
- Your proxy provider may need to whitelist our IP of 204.15.192.195
-
+
Tip : "Residential" and "Mobile" proxy type can be more successfull than "Data Center" for blocked websites.
diff --git a/changedetectionio/templates/settings.html b/changedetectionio/templates/settings.html
index e13bbe60c..752ff27e8 100644
--- a/changedetectionio/templates/settings.html
+++ b/changedetectionio/templates/settings.html
@@ -214,7 +214,7 @@ nav
-
+
Chrome Webstore
diff --git a/changedetectionio/templates/watch-overview.html b/changedetectionio/templates/watch-overview.html
index 3cdaaf5b7..3e248ea2e 100644
--- a/changedetectionio/templates/watch-overview.html
+++ b/changedetectionio/templates/watch-overview.html
@@ -119,7 +119,7 @@
or ( watch.get_fetch_backend == "system" and system_default_fetcher == 'html_webdriver' )
or "extra_browser_" in watch.get_fetch_backend
%}
-
+
{% endif %}
{%if watch.is_pdf %} {% endif %}
From e37467f6497b544545e437d8380348d8bc28560c Mon Sep 17 00:00:00 2001
From: dgtlmoon
Date: Wed, 19 Feb 2025 10:44:54 +0100
Subject: [PATCH 09/23] UI - More W3C HTML validation fixes
---
changedetectionio/forms.py | 2 +-
changedetectionio/static/images/copy.svg | 2 +-
changedetectionio/static/images/email.svg | 2 +-
changedetectionio/static/images/schedule.svg | 2 +-
changedetectionio/templates/_common_fields.html | 2 +-
changedetectionio/templates/edit.html | 4 ++--
changedetectionio/templates/svgs/search-icon.svg | 2 +-
7 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/changedetectionio/forms.py b/changedetectionio/forms.py
index 11792d622..d4b8e3425 100644
--- a/changedetectionio/forms.py
+++ b/changedetectionio/forms.py
@@ -171,7 +171,7 @@ class validateTimeZoneName(object):
class ScheduleLimitDaySubForm(Form):
enabled = BooleanField("not set", default=True)
- start_time = TimeStringField("Start At", default="00:00", render_kw={"placeholder": "HH:MM"}, validators=[validators.Optional()])
+ start_time = TimeStringField("Start At", default="00:00", validators=[validators.Optional()])
duration = FormField(TimeDurationForm, label="Run duration")
class ScheduleLimitForm(Form):
diff --git a/changedetectionio/static/images/copy.svg b/changedetectionio/static/images/copy.svg
index e3f791575..b2758f608 100644
--- a/changedetectionio/static/images/copy.svg
+++ b/changedetectionio/static/images/copy.svg
@@ -1,7 +1,7 @@
{{ render_field(form.notification_body , rows=5, class="notification-body", placeholder=settings_application['notification_body']) }}
-
Body for all notifications ‐ You can use Jinja2 templating in the notification title, body and URL, and tokens from below.
+ Body for all notifications ‐ You can use Jinja2 templating in the notification title, body and URL, and tokens from below.
diff --git a/changedetectionio/templates/edit.html b/changedetectionio/templates/edit.html
index 2560cf665..03b9aec39 100644
--- a/changedetectionio/templates/edit.html
+++ b/changedetectionio/templates/edit.html
@@ -40,7 +40,7 @@
- General
+ General
Request
{% if extra_tab_content %}
{{ extra_tab_content }}
@@ -224,7 +224,7 @@ Math: {{ 1 + 1 }}") }}
Click here to Start
-
+
Please allow 10-15 seconds for the browser to connect.
diff --git a/changedetectionio/templates/svgs/search-icon.svg b/changedetectionio/templates/svgs/search-icon.svg
index d1e3248c3..93860c180 100644
--- a/changedetectionio/templates/svgs/search-icon.svg
+++ b/changedetectionio/templates/svgs/search-icon.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
From bdd9760f3c9f81554ae5ee824fe60c5de65db9dd Mon Sep 17 00:00:00 2001
From: dgtlmoon
Date: Wed, 19 Feb 2025 10:46:22 +0100
Subject: [PATCH 10/23] Update docker-compose.yml
---
docker-compose.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docker-compose.yml b/docker-compose.yml
index 29b60b16c..bf21f65ad 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -81,7 +81,7 @@ services:
# Sockpuppetbrowser is basically chrome wrapped in an API for allowing fast fetching of web-pages.
- # RECOMMENDED FOR FETCHING PAGES WITH CHROME
+ # RECOMMENDED FOR FETCHING PAGES WITH CHROME, be sure to enable the "PLAYWRIGHT_DRIVER_URL" env variable in the main changedetection container
# sockpuppetbrowser:
# hostname: sockpuppetbrowser
# image: dgtlmoon/sockpuppetbrowser:latest
From 24c3bfe5ad75649fbee9faf99b529cd14500c7e4 Mon Sep 17 00:00:00 2001
From: dgtlmoon
Date: Wed, 19 Feb 2025 14:18:18 +0100
Subject: [PATCH 11/23] UI - Make the setup and error messages for Visual
Selector and Browser Steps a lot more meaningful (#2977)
---
changedetectionio/flask_app.py | 9 +++----
changedetectionio/templates/_helpers.html | 12 +++++++++
changedetectionio/templates/edit.html | 30 ++++++++++++-----------
3 files changed, 32 insertions(+), 19 deletions(-)
diff --git a/changedetectionio/flask_app.py b/changedetectionio/flask_app.py
index f603e0121..a88df4761 100644
--- a/changedetectionio/flask_app.py
+++ b/changedetectionio/flask_app.py
@@ -875,14 +875,14 @@ def changedetection_app(config=None, datastore_o=None):
system_uses_webdriver = datastore.data['settings']['application']['fetch_backend'] == 'html_webdriver'
- is_html_webdriver = False
+ watch_uses_webdriver = False
if (watch.get('fetch_backend') == 'system' and system_uses_webdriver) or watch.get('fetch_backend') == 'html_webdriver' or watch.get('fetch_backend', '').startswith('extra_browser_'):
- is_html_webdriver = True
+ watch_uses_webdriver = True
from zoneinfo import available_timezones
# Only works reliably with Playwright
- visualselector_enabled = os.getenv('PLAYWRIGHT_DRIVER_URL', False) and is_html_webdriver
+
template_args = {
'available_processors': processors.available_processors(),
'available_timezones': sorted(available_timezones()),
@@ -895,14 +895,13 @@ def changedetection_app(config=None, datastore_o=None):
'has_default_notification_urls': True if len(datastore.data['settings']['application']['notification_urls']) else False,
'has_extra_headers_file': len(datastore.get_all_headers_in_textfile_for_watch(uuid=uuid)) > 0,
'has_special_tag_options': _watch_has_tag_options_set(watch=watch),
- 'is_html_webdriver': is_html_webdriver,
+ 'watch_uses_webdriver': watch_uses_webdriver,
'jq_support': jq_support,
'playwright_enabled': os.getenv('PLAYWRIGHT_DRIVER_URL', False),
'settings_application': datastore.data['settings']['application'],
'timezone_default_config': datastore.data['settings']['application'].get('timezone'),
'using_global_webdriver_wait': not default['webdriver_delay'],
'uuid': uuid,
- 'visualselector_enabled': visualselector_enabled,
'watch': watch
}
diff --git a/changedetectionio/templates/_helpers.html b/changedetectionio/templates/_helpers.html
index 85fb5969e..8dd16ff30 100644
--- a/changedetectionio/templates/_helpers.html
+++ b/changedetectionio/templates/_helpers.html
@@ -61,6 +61,18 @@
{{ field(**kwargs)|safe }}
{% endmacro %}
+{% macro playwright_warning() %}
+ Error - Playwright support for Chrome based fetching is not enabled. Alternatively try our very affordable subscription based service which has all this setup for you .
+ You may need to Enable playwright environment variable and uncomment the sockpuppetbrowser in the docker-compose.yml file.
+
+ (Also Selenium/WebDriver can not extract full page screenshots reliably so Playwright is recommended here)
+
+{% endmacro %}
+
+{% macro only_webdriver_type_watches_warning() %}
+ Sorry, this functionality only works with Playwright/Chrome enabled watches. You need to Set the fetch method to Playwright/Chrome mode and resave and have the Playwright connection enabled.
+{% endmacro %}
+
{% macro render_time_schedule_form(form, available_timezones, timezone_default_config) %}