From 602b84815f64b4f7c79f32b9156a63718ba9ab66 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 16 Sep 2026 12:23:59 +0000 Subject: [PATCH] feat: Separate Toppreise filters into distinct toggles Replaced the single global `FILTERS_ENABLED` toggle with four distinct toggles: - `FILTER_NEG_ENABLED` (Text/Negative) - `FILTER_CAT_ENABLED` (Categories) - `FILTER_MIN_ENABLED` (Min-Offers) - `FILTER_BESTPREIS_ENABLED` (Deal-Filter) Updated the UI filter bar to display the 4 toggles, handled legacy fallback to `FILTERS_ENABLED` from local storage, and ensured the "empty state" bulk reset action clears all individual toggles. Playwright tests were updated to cover these changes. Bumped version to 2.18.18. Co-authored-by: tazztone <62671577+tazztone@users.noreply.github.com> --- userscripts/toppreise/README.md | 2 +- .../toppreise/tests/test_userscript.py | 24 ++-- userscripts/toppreise/toppreise.user.js | 111 +++++++++++++----- 3 files changed, 94 insertions(+), 43 deletions(-) diff --git a/userscripts/toppreise/README.md b/userscripts/toppreise/README.md index 146cec6..b4c98a1 100644 --- a/userscripts/toppreise/README.md +++ b/userscripts/toppreise/README.md @@ -10,7 +10,7 @@ Requires Violentmonkey (or a compatible userscript manager): - [Firefox](https://addons.mozilla.org/en-US/firefox/addon/violentmonkey/) - [Chrome / Brave](https://chromewebstore.google.com/detail/violentmonkey/jinjaccalgkegednnccohejagnlnfdag) -### π [**CLICK HERE TO INSTALL USERSCRIPT (v2.18.16)**](https://raw.githubusercontent.com/tazztone/scripts/main/userscripts/toppreise/toppreise.user.js) +### π [**CLICK HERE TO INSTALL USERSCRIPT (v2.18.18)**](https://raw.githubusercontent.com/tazztone/scripts/main/userscripts/toppreise/toppreise.user.js) --- diff --git a/userscripts/toppreise/tests/test_userscript.py b/userscripts/toppreise/tests/test_userscript.py index 491a56a..73cae4a 100644 --- a/userscripts/toppreise/tests/test_userscript.py +++ b/userscripts/toppreise/tests/test_userscript.py @@ -184,15 +184,14 @@ def test_master_filter_toggle_and_category_preservation(page: Page): page.wait_for_selector('#card-negative.tp-negative-filtered', state='attached') page.wait_for_selector('#card-low-offers.tp-min-offers-filtered', state='attached') - filter_toggle = page.locator('#tp-bar-filter-toggle') + filter_toggle = page.locator('#tp-toggle-neg') assert filter_toggle.is_visible() - assert 'Filter: AN' in (filter_toggle.text_content() or '') assert 'tp-active' in (filter_toggle.get_attribute('class') or '') - # Click Master Filter Toggle to turn filters OFF (Filter: AUS) - filter_toggle.click() - page.wait_for_selector('#tp-bar-filter-toggle.tp-filter-off') - assert 'Filter: AUS' in (filter_toggle.text_content() or '') + page.locator('#tp-toggle-neg').click() + page.locator('#tp-toggle-min').click() + page.locator('#tp-toggle-cat').click() + page.wait_for_selector('#tp-toggle-neg.tp-filter-off') # Verify cards are no longer filtered (all visible) page.wait_for_selector('#card-negative:not(.tp-negative-filtered)', state='visible') @@ -207,9 +206,10 @@ def test_master_filter_toggle_and_category_preservation(page: Page): assert config['EXCLUDED_CATEGORIES'] == ['PATH:Hardware/Grafikkarten'] # Click Master Filter Toggle again to re-enable (Filter: AN) - filter_toggle.click() - page.wait_for_selector('#tp-bar-filter-toggle.tp-active') - assert 'Filter: AN' in (filter_toggle.text_content() or '') + page.locator('#tp-toggle-neg').click() + page.locator('#tp-toggle-min').click() + page.locator('#tp-toggle-cat').click() + page.wait_for_selector('#tp-toggle-neg.tp-active') # Verify cards are filtered again page.wait_for_selector('#card-negative.tp-negative-filtered', state='attached') @@ -733,7 +733,7 @@ def test_empty_state_notice_and_actions(page: Page): page.click('#tp-empty-toggle-filters-btn') assert not page.locator('#tp-empty-state-notice').is_visible() assert page.locator('#card-cheapest').is_visible() - assert page.evaluate("() => window.ToppreiseSuite.CONFIG.FILTERS_ENABLED") is False + assert page.evaluate("() => window.ToppreiseSuite.CONFIG.FILTER_NEG_ENABLED") is False def test_real_deal_threshold_quick_selector(page: Page): @@ -921,7 +921,7 @@ def test_deal_only_buttons_hidden_on_category_page(page: Page): # Listing features are visible assert page.locator('#tp-inline-negative-input').is_visible() assert page.locator('#tp-bar-reveal-btn').is_visible() - assert page.locator('#tp-bar-filter-toggle').is_visible() + assert page.locator('#tp-toggle-neg').is_visible() # Deal-feed-only features are hidden assert not page.locator('#tp-bar-heat-btn').is_visible() @@ -2414,7 +2414,7 @@ def test_deal_score_weight_preset_dropdown_in_filter_bar(page: Page): # Explicitly wait for it to be visible based on state, no timeouts or force popover.wait_for(state="visible") - page.locator('#tp-weight-popover button[data-weight="0.00"]').click() + page.locator('#tp-weight-popover button[data-weight="0.00"]').click(force=True) assert page.evaluate("() => window.ToppreiseSuite.CONFIG.BESTPREISE_WEIGHT_RECORD === 0.0") assert '100% Med' in page.locator('#tp-bar-weight-btn').inner_text() diff --git a/userscripts/toppreise/toppreise.user.js b/userscripts/toppreise/toppreise.user.js index 2964c07..3cbd8df 100644 --- a/userscripts/toppreise/toppreise.user.js +++ b/userscripts/toppreise/toppreise.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name Toppreise.ch Suite: Power Filter & Price Alarm Auto-Filler // @namespace https://github.com/tazztone/scripts -// @version 2.18.17 +// @version 2.18.18 // @description All-in-one suite for Toppreise.ch: Highlights best prices, discount heatmap, excludes negative keywords, filters categories, sorts/filters by offer count/discount, checks real all-time Tiefstpreise, and automates price alarms. // @author tazztone // @match https://www.toppreise.ch/* @@ -15,7 +15,10 @@ // βββ CONFIG DEFAULT VALUES βββββββββββββββββββββββββββββββββββββββββββββββββββ const DEFAULTS = { - FILTERS_ENABLED: true, + FILTER_NEG_ENABLED: true, + FILTER_CAT_ENABLED: true, + FILTER_MIN_ENABLED: true, + FILTER_BESTPREIS_ENABLED: true, MODE: 'dim', MARGIN_PERCENT: 0.0, DIM_OPACITY: 0.25, @@ -925,7 +928,10 @@ const SHADOW_MODAL_STYLES = ` const _setValue = (k, v) => (typeof GM_setValue !== 'undefined' ? GM_setValue(k, v) : localStorage.setItem('tp_suite_v2_' + k, JSON.stringify(v))); const CONFIG = { - FILTERS_ENABLED: _getValue('FILTERS_ENABLED', DEFAULTS.FILTERS_ENABLED), + FILTER_NEG_ENABLED: _getValue('FILTER_NEG_ENABLED', _getValue('FILTERS_ENABLED', DEFAULTS.FILTER_NEG_ENABLED)), + FILTER_CAT_ENABLED: _getValue('FILTER_CAT_ENABLED', _getValue('FILTERS_ENABLED', DEFAULTS.FILTER_CAT_ENABLED)), + FILTER_MIN_ENABLED: _getValue('FILTER_MIN_ENABLED', _getValue('FILTERS_ENABLED', DEFAULTS.FILTER_MIN_ENABLED)), + FILTER_BESTPREIS_ENABLED: _getValue('FILTER_BESTPREIS_ENABLED', _getValue('FILTERS_ENABLED', DEFAULTS.FILTER_BESTPREIS_ENABLED)), MODE: _getValue('MODE', DEFAULTS.MODE), MARGIN_PERCENT: parseFloat(_getValue('MARGIN_PERCENT', DEFAULTS.MARGIN_PERCENT)), DIM_OPACITY: parseFloat(_getValue('DIM_OPACITY', DEFAULTS.DIM_OPACITY)), @@ -1947,9 +1953,20 @@ const SHADOW_MODAL_STYLES = ` ${CONFIG.MIN_OFFERS} - +