Compare commits

..

3 Commits

Author SHA1 Message Date
dgtlmoon
f52e98f6fc Adding automated test for sending single test notification from a watch 2025-10-30 14:29:30 +01:00
dgtlmoon
a0b994cf54 Adding deeper test 2025-10-30 14:15:27 +01:00
dgtlmoon
2c0ba999af Improved send test notification handling 2025-10-30 14:09:42 +01:00
10 changed files with 45 additions and 124 deletions

View File

@@ -69,7 +69,7 @@ jobs:
- uses: actions/checkout@v5
- name: Download Docker image artifact
uses: actions/download-artifact@v6
uses: actions/download-artifact@v5
with:
name: test-changedetectionio-${{ env.PYTHON_VERSION }}
path: /tmp
@@ -96,7 +96,7 @@ jobs:
- uses: actions/checkout@v5
- name: Download Docker image artifact
uses: actions/download-artifact@v6
uses: actions/download-artifact@v5
with:
name: test-changedetectionio-${{ env.PYTHON_VERSION }}
path: /tmp
@@ -135,7 +135,7 @@ jobs:
- uses: actions/checkout@v5
- name: Download Docker image artifact
uses: actions/download-artifact@v6
uses: actions/download-artifact@v5
with:
name: test-changedetectionio-${{ env.PYTHON_VERSION }}
path: /tmp
@@ -177,7 +177,7 @@ jobs:
- uses: actions/checkout@v5
- name: Download Docker image artifact
uses: actions/download-artifact@v6
uses: actions/download-artifact@v5
with:
name: test-changedetectionio-${{ env.PYTHON_VERSION }}
path: /tmp
@@ -217,7 +217,7 @@ jobs:
- uses: actions/checkout@v5
- name: Download Docker image artifact
uses: actions/download-artifact@v6
uses: actions/download-artifact@v5
with:
name: test-changedetectionio-${{ env.PYTHON_VERSION }}
path: /tmp
@@ -253,7 +253,7 @@ jobs:
- uses: actions/checkout@v5
- name: Download Docker image artifact
uses: actions/download-artifact@v6
uses: actions/download-artifact@v5
with:
name: test-changedetectionio-${{ env.PYTHON_VERSION }}
path: /tmp
@@ -282,7 +282,7 @@ jobs:
- uses: actions/checkout@v5
- name: Download Docker image artifact
uses: actions/download-artifact@v6
uses: actions/download-artifact@v5
with:
name: test-changedetectionio-${{ env.PYTHON_VERSION }}
path: /tmp
@@ -322,7 +322,7 @@ jobs:
- uses: actions/checkout@v5
- name: Download Docker image artifact
uses: actions/download-artifact@v6
uses: actions/download-artifact@v5
with:
name: test-changedetectionio-${{ env.PYTHON_VERSION }}
path: /tmp
@@ -353,7 +353,7 @@ jobs:
- uses: actions/checkout@v5
- name: Download Docker image artifact
uses: actions/download-artifact@v6
uses: actions/download-artifact@v5
with:
name: test-changedetectionio-${{ env.PYTHON_VERSION }}
path: /tmp
@@ -398,7 +398,7 @@ jobs:
- uses: actions/checkout@v5
- name: Download Docker image artifact
uses: actions/download-artifact@v6
uses: actions/download-artifact@v5
with:
name: test-changedetectionio-${{ env.PYTHON_VERSION }}
path: /tmp

View File

@@ -2,7 +2,7 @@
# Read more https://github.com/dgtlmoon/changedetection.io/wiki
__version__ = '0.50.39'
__version__ = '0.50.37'
from changedetectionio.strtobool import strtobool
from json.decoder import JSONDecodeError

View File

@@ -96,10 +96,7 @@ def build_watch_json_schema(d):
"enum": ["html_requests", "html_webdriver"]
})
schema['properties']['processor'] = {"anyOf": [
{"type": "string", "enum": ["restock_diff", "text_json_diff"]},
{"type": "null"}
]}
# All headers must be key/value type dict
schema['properties']['headers'] = {

View File

@@ -20,14 +20,10 @@ class NotificationContextData(dict):
'base_url': None,
'current_snapshot': None,
'diff': None,
'diff_clean': None,
'diff_added': None,
'diff_added_clean': None,
'diff_full': None,
'diff_full_clean': None,
'diff_patch': None,
'diff_removed': None,
'diff_removed_clean': None,
'diff_url': None,
'markup_text_links_to_html_links': False, # If automatic conversion of plaintext to HTML should happen
'notification_timestamp': time.time(),
@@ -80,14 +76,10 @@ def set_basic_notification_vars(snapshot_contents, current_snapshot, prev_snapsh
n_object = {
'current_snapshot': snapshot_contents,
'diff': diff.render_diff(prev_snapshot, current_snapshot),
'diff_clean': diff.render_diff(prev_snapshot, current_snapshot, include_change_type_prefix=False),
'diff_added': diff.render_diff(prev_snapshot, current_snapshot, include_removed=False),
'diff_added_clean': diff.render_diff(prev_snapshot, current_snapshot, include_removed=False, include_change_type_prefix=False),
'diff_full': diff.render_diff(prev_snapshot, current_snapshot, include_equal=True),
'diff_full_clean': diff.render_diff(prev_snapshot, current_snapshot, include_equal=True, include_change_type_prefix=False),
'diff_patch': diff.render_diff(prev_snapshot, current_snapshot, patch_format=True),
'diff_removed': diff.render_diff(prev_snapshot, current_snapshot, include_added=False),
'diff_removed_clean': diff.render_diff(prev_snapshot, current_snapshot, include_added=False, include_change_type_prefix=False),
'screenshot': watch.get_screenshot() if watch and watch.get('notification_screenshot') else None,
'triggered_text': triggered_text,
'uuid': watch.get('uuid') if watch else None,

View File

@@ -87,35 +87,19 @@
<tr>
<td><code>{{ '{{diff}}' }}</code></td>
<td>The diff output - only changes, additions, and removals</td>
</tr>
<tr>
<td><code>{{ '{{diff_clean}}' }}</code></td>
<td>The diff output - only changes, additions, and removals &dash; <i>Without (added) prefix or colors</i></td>
</tr>
<tr>
<td><code>{{ '{{diff_added}}' }}</code></td>
<td>The diff output - only changes and additions</td>
</tr>
<tr>
<td><code>{{ '{{diff_added_clean}}' }}</code></td>
<td>The diff output - only changes and additions &dash; <i>Without (added) prefix or colors</i></td>
</tr>
<tr>
<td><code>{{ '{{diff_removed}}' }}</code></td>
<td>The diff output - only changes and removals</td>
</tr>
<tr>
<td><code>{{ '{{diff_removed_clean}}' }}</code></td>
<td>The diff output - only changes and removals &dash; <i>Without (added) prefix or colors</i></td>
</tr>
<tr>
<td><code>{{ '{{diff_full}}' }}</code></td>
<td>The diff output - full difference output</td>
</tr>
<tr>
<td><code>{{ '{{diff_full_clean}}' }}</code></td>
<td>The diff output - full difference output &dash; <i>Without (added) prefix or colors</i></td>
</tr>
<tr>
<td><code>{{ '{{diff_patch}}' }}</code></td>
<td>The diff output - patch in unified format</td>

View File

@@ -158,7 +158,6 @@ def test_check_notification_plaintext_format(client, live_server, measure_memory
assert ADDED_PLACEMARKER_OPEN not in subject
assert 'diff added didnt split' not in subject
assert '(changed) Which is across' in subject
assert 'PLACEMARKER' not in subject
# The email should be plain text only (not multipart)
assert not msg.is_multipart()
@@ -227,7 +226,6 @@ def test_check_notification_html_color_format(client, live_server, measure_memor
assert ADDED_PLACEMARKER_OPEN not in subject
assert 'diff added didnt split' not in subject
assert '(changed) Which is across' in subject
assert 'PLACEMARKER' not in subject
assert 'head title' in subject
assert "span" not in subject
assert 'background-color' not in subject
@@ -585,7 +583,6 @@ def test_check_plaintext_document_html_notifications(client, live_server, measur
# Should be the HTML, but not HTML Color
assert 'background-color' not in html_content
assert '<br>(added) And let&#39;s talk about &lt;title&gt; tags<br>' in html_content
assert 'PLACEMARKER' not in html_content
assert '&lt;br' not in html_content
assert '<pre role="article"' in html_content # Should have got wrapped nicely in email_helpers.py
@@ -716,7 +713,6 @@ def test_check_html_document_plaintext_notification(client, live_server, measure
assert '<tag>' in body # Should have got converted from original HTML to plaintext
assert '(changed) some stuff\r\n' in body
assert 'PLACEMARKER' not in body
assert '(into) sxome stuff\r\n' in body
assert '(added) lets slip this in\r\n' in body
assert '(added) and this in\r\n' in body

View File

@@ -14,6 +14,7 @@ class Weekday(IntEnum):
Saturday = 5
Sunday = 6
@lru_cache(maxsize=100)
def am_i_inside_time(
day_of_week: str,
time_str: str,

View File

@@ -28,7 +28,7 @@ info:
For example: `x-api-key: YOUR_API_KEY`
version: 0.1.3
version: 0.1.2
contact:
name: ChangeDetection.io
url: https://github.com/dgtlmoon/changedetection.io
@@ -65,17 +65,13 @@ tags:
- name: Watch History
description: |
Get a list of timestamps of all changes detected for a watch.
Access historical snapshots and change data for your watches. View the complete timeline of detected changes
and retrieve specific versions of monitored content for comparison and analysis.
- name: Snapshots
description: |
Retrieve individual text snapshot of monitored content according to the `timestamp`. The text snapshot is the HTML
to Text at page check time.
Set the query argument `html` to any value to retrieve the last HTML fetched, the system only keeps the last two
(2) HTML files fetched.
Use the Watch History API endpoint to get a list of timestamps to pass to this query.
Retrieve individual snapshots of monitored content. Access both the processed change detection data and
the raw HTML content that was captured during monitoring checks.
- name: Favicon
description: |
@@ -232,11 +228,6 @@ components:
maxLength: 5000
required: [operation, selector, optional_value]
description: Browser automation steps
processor:
type: string
enum: [restock_diff, text_json_diff]
default: text_json_diff
description: Optional processor mode to use for change detection. Defaults to `text_json_diff` if not specified.
Watch:
allOf:
@@ -437,15 +428,7 @@ paths:
operationId: createWatch
tags: [Watch Management]
summary: Create a new watch
description: |
Create a single web page change monitor (watch). Requires at least `url` to be set.
Every watch can be configured with:
- **Processor mode**: `processor` field (`restock_diff` or `text_json_diff` - default)
- **Notification settings**: `notification_urls` (array), `notification_title`, `notification_body`, `notification_format`, `notification_muted`
- **Tags/Groups**: `tag` (UUID string) or `tags` (array of UUIDs)
- **Check settings**: `time_between_check`, `paused`, `method`, `fetch_backend`
- **Advanced options**: `headers`, `body`, `proxy`, `browser_steps`, and more
description: Create a single web page change monitor (watch). Requires at least 'url' to be set.
x-code-samples:
- lang: 'curl'
source: |
@@ -463,7 +446,7 @@ paths:
source: |
import requests
import json
headers = {
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
@@ -475,7 +458,7 @@ paths:
'hours': 1
}
}
response = requests.post('http://localhost:5000/api/v1/watch',
response = requests.post('http://localhost:5000/api/v1/watch',
headers=headers, json=data)
print(response.text)
requestBody:
@@ -665,9 +648,7 @@ paths:
operationId: getWatchHistory
tags: [Watch History]
summary: Get watch history
description: |
Get a list of all historical snapshots available for a web page change monitor (watch), use the key `timestamp`
as the query argument for fetching a single watch history snapshot.
description: Get a list of all historical snapshots available for a web page change monitor (watch)
x-code-samples:
- lang: 'curl'
source: |
@@ -707,9 +688,7 @@ paths:
operationId: getWatchSnapshot
tags: [Snapshots]
summary: Get single snapshot
description: |
Get single snapshot from web page change monitor (watch). Use 'latest' for the most recent snapshot.
Use the Watch History API to get a list of timestamps to pass.
description: Get single snapshot from web page change monitor (watch). Use 'latest' for the most recent snapshot.
x-code-samples:
- lang: 'curl'
source: |

File diff suppressed because one or more lines are too long

View File

@@ -12,7 +12,7 @@ janus # Thread-safe async/sync queue bridge
flask_wtf~=1.2
flask~=3.1
flask-socketio~=5.5.1
python-socketio~=5.14.3
python-socketio~=5.14.2
python-engineio~=4.12.3
inscriptis~=2.2
pytz
@@ -31,7 +31,7 @@ requests-file
chardet>2.3.0
wtforms~=3.2
jsonpath-ng~=1.7.0
jsonpath-ng~=1.5.3
# dnspython - Used by paho-mqtt for MQTT broker resolution
# Version pin removed since eventlet (which required the specific 2.6.1 pin) has been eliminated
@@ -87,7 +87,7 @@ pyppeteerstealth>=0.0.4
# Include pytest, so if theres a support issue we can ask them to run these tests on their setup
pytest ~=7.2
pytest-flask ~=1.3
pytest-flask ~=1.2
pytest-mock ~=3.15
# Anything 4.0 and up but not 5.0