{% extends 'base.html' %} {% block content %} {% from '_helpers.html' import render_field, render_checkbox_field, render_button %} {% from '_common_fields.html' import render_common_settings_form %} {% if playwright_enabled %} {% endif %} {% set has_tag_filters_extra="WARNING: Watch has tag/groups set with special filters\n" if has_special_tag_options else '' %}
{{ render_field(form.url, placeholder="https://...", required=true, class="m-d") }} Some sites use JavaScript to create the content, for this you should use the Chrome/WebDriver Fetcher
You can use variables in the URL, perfect for inserting the current date and other logic, help and examples here
{{ render_field(form.processor) }}
{{ render_field(form.title, class="m-d") }}
{{ render_field(form.tags) }} Organisational tag/group name used in the main listing page
{{ render_field(form.time_between_check, class="time-check-widget") }} {{ render_checkbox_field(form.time_between_check_use_default, class="use-default-timecheck") }}
{{ render_checkbox_field(form.extract_title_as_title) }}
{{ render_checkbox_field(form.filter_failure_notification_send) }} Sends a notification when the filter can no longer be seen on the page, good for knowing when the page changed and your filter will not work anymore.
{{ render_field(form.fetch_backend, class="fetch-backend") }}

Use the Basic method (default) where your watched site doesn't need Javascript to render.

The Chrome/Javascript method requires a network connection to a running WebDriver+Chrome server, set by the ENV var 'WEBDRIVER_URL'.

Tip: Connect using Bright Data and Oxylabs Proxies, find out more here.
{% if form.proxy %}
{{ form.proxy.label }} Check/Scan all
{{ form.proxy(class="fetch-backend-proxy") }}
Choose a proxy for this watch
{% endif %}
{{ render_field(form.webdriver_delay) }}
If you're having trouble waiting for the page to be fully rendered (text missing etc), try increasing the 'wait' time here.
This will wait n seconds before extracting the text. {% if using_global_webdriver_wait %}
Using the current global default settings {% endif %}
{% if playwright_enabled %}

Click here to Start


Please allow 10-15 seconds for the browser to connect.
Loading (?) {{ render_field(form.browser_steps) }}
{% endif %}
{{ render_checkbox_field(form.notification_muted) }}
{% if is_html_webdriver %}
{{ render_checkbox_field(form.notification_screenshot) }} Use with caution! This will easily fill up your email storage quota or flood other storages.
{% endif %}
{% if has_default_notification_urls %}
Look out! There are system-wide notification URLs enabled, this form will override notification settings for this watch only ‐ an empty Notification URL list here will still send notifications.
{% endif %} Use system defaults {{ render_common_settings_form(form, emailprefix, settings_application, extra_notification_token_placeholder_info) }}
{% if watch['processor'] == 'text_json_diff' %}
Activate preview
Pro-tips:
  • Use the preview page to see your filters and triggers highlighted.
  • Some sites use JavaScript to create the content, for this you should use the Chrome/WebDriver Fetcher
{% set field = render_field(form.include_filters, rows=5, placeholder=has_tag_filters_extra+"#example xpath://body/div/span[contains(@class, 'example-class')]", class="m-d") %} {{ field }} {% if '/text()' in field %} Note!: //text() function does not work where the <element> contains <![CDATA[]]>
{% endif %} One CSS, xPath, JSON Path/JQ selector per line, any rules that matches will be used.

Show advanced help and tips

{{ render_field(form.subtractive_selectors, rows=5, placeholder=has_tag_filters_extra+"header footer nav .stockticker //*[contains(text(), 'Advertisement')]") }}
  • Remove HTML element(s) by CSS and XPath selectors before text conversion.
  • Don't paste HTML here, use only CSS and XPath selectors
  • Add multiple elements, CSS or XPath selectors per line to ignore multiple parts of the HTML.

Text filtering

Limit trigger/ignore/block/extract to;
{{ render_checkbox_field(form.filter_text_added) }} {{ render_checkbox_field(form.filter_text_replaced) }} {{ render_checkbox_field(form.filter_text_removed) }} Note: Depending on the length and similarity of the text on each line, the algorithm may consider an addition instead of replacement for example. So it's always better to select Added+Replaced when you're interested in new content.
When content is merely moved in a list, it will also trigger an addition, consider enabling Only trigger when unique lines appear
{{ render_checkbox_field(form.check_unique_lines) }} Good for websites that just move the content around, and you want to know when NEW content is added, compares new lines against all history for this watch.
{{ render_checkbox_field(form.remove_duplicate_lines) }} Remove duplicate lines of text
{{ render_checkbox_field(form.sort_text_alphabetically) }} Helps reduce changes detected caused by sites shuffling lines around, combine with check unique lines below.
{{ render_checkbox_field(form.trim_text_whitespace) }} Remove any whitespace before and after each line of text
{{ render_field(form.trigger_text, rows=5, placeholder="Some text to wait for in a line /some.regex\d{2}/ for case-INsensitive regex ") }}
  • Text to wait for before triggering a change/notification, all text and regex are tested case-insensitive.
  • Trigger text is processed from the result-text that comes out of any CSS/JSON Filters for this watch
  • Each line is processed separately (think of each line as "OR")
  • Note: Wrap in forward slash / to use regex example: /foo\d/
{{ render_field(form.ignore_text, rows=5, placeholder="Some text to ignore in a line /some.regex\d{2}/ for case-INsensitive regex ") }}
  • Matching text will be removed from the text snapshot
  • Each line processed separately, any line matching will be ignored (removed before creating the checksum)
  • Regular Expression support, wrap the entire line in forward slash /regex/
  • Changing this will affect the comparison checksum which may trigger an alert
{{ render_field(form.text_should_not_be_present, rows=5, placeholder="For example: Out of stock Sold out Not in stock Unavailable") }}
  • Block change-detection while this text is on the page, all text and regex are tested case-insensitive, good for waiting for when a product is available again
  • Block text is processed from the result-text that comes out of any CSS/JSON Filters for this watch
  • All lines here must not exist (think of each line as "OR")
  • Note: Wrap in forward slash / to use regex example: /foo\d/
{{ render_field(form.extract_text, rows=5, placeholder="/\d+ online/ or keyword") }}
  • Extracts text in the final output (line by line) after other filters using regular expressions or string match;
    • Regular expression ‐ example /reports.+?2022/i
    • Don't forget to consider the white-space at the start of a line /.+?reports.+?2022/i
    • Use //(?aiLmsux)) type flags (more information here)
    • Keyword example ‐ example Out of stock
    • Use groups to extract just that text ‐ example /reports.+?(\d+)/i returns a list of years only
    • Example - match lines containing a keyword /.*icecream.*/
  • One line per regular-expression/string match
{% endif %} {# rendered sub Template #} {% if extra_form_content %}
{{ extra_form_content|safe }}
{% endif %} {% if watch['processor'] == 'text_json_diff' %}
{% if visualselector_enabled %} The Visual Selector tool lets you select the text elements that will be used for the change detection. It automatically fills-in the filters in the "CSS/JSONPath/JQ/XPath Filters" box of the Filters & Triggers tab. Use Shift+Click to select multiple items.
Clear selection One moment, fetching screenshot and element information..
Currently: Loading...
{% else %}

Sorry, this functionality only works with Playwright/Chrome enabled watches.

Enable the Playwright Chrome fetcher, or alternatively try our very affordable subscription based service.

This is because Selenium/WebDriver can not extract full page screenshots reliably.

{% endif %}
{% endif %}
Check count {{ "{:,}".format( watch.check_count) }}
Consecutive filter failures {{ "{:,}".format( watch.consecutive_filter_failures) }}
History length {{ "{:,}".format(watch.history|length) }}
Last fetch duration {{ watch.fetch_time }}s
Notification alert count {{ watch.notification_alert_count }}
Server type reply {{ watch.get('remote_server_reply') }}
{% if watch.history_n %}

Download latest HTML snapshot

{% endif %}
{{ render_button(form.save_button) }} Delete Clear History Create Copy
{% endblock %}