Commit Graph
88 Commits
Author SHA1 Message Date
steveandClaude Opus 4.6 adefaaef36 feat: add SetDefaultTimeout to InteractiveBrowser interface
CI / test (push) Successful in 45s
CI / vet (push) Successful in 49s
CI / build (push) Successful in 50s
Adds SetDefaultTimeout(time.Duration) to the InteractiveBrowser interface,
delegating to Playwright's Page and BrowserContext SetDefaultTimeout and
SetDefaultNavigationTimeout methods. This allows callers to set a timeout
so Playwright operations return an error instead of blocking forever when
the browser process crashes or the remote server becomes unresponsive.

Closes #86

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-03-17 01:59:16 +00:00
steveandClaude Opus 4.6 84e811572b fix: sanitize cookie expires for Playwright compatibility
CI / build (pull_request) Successful in 1m51s
CI / vet (pull_request) Successful in 2m38s
CI / test (pull_request) Successful in 2m59s
Playwright requires cookie expires to be either -1 (session cookie) or
a positive unix timestamp. When a cookie has no expiry (zero time.Time),
.Unix() returns -62135596800 which Playwright rejects. Cookies with
non-positive timestamps (e.g. Cloudflare's __cf_bm) also fail.

Now treats zero time or non-positive unix timestamps as session cookies
by setting expires to -1.

Fixes #84

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-03-13 01:28:45 +00:00
steve 61b68adfd0 Merge pull request 'fix: address Playwright API audit findings' (#83) from fix/playwright-api-audit into main
CI / test (push) Successful in 34s
CI / vet (push) Successful in 47s
CI / build (push) Successful in 48s
Reviewed-on: #83
2026-03-02 04:59:43 +00:00
steveandClaude Opus 4.6 0447f1bdbe fix: address Playwright API audit findings
CI / test (pull_request) Successful in 34s
CI / vet (pull_request) Successful in 48s
CI / build (pull_request) Successful in 49s
- Replace deprecated Locator.Type() with PressSequentially() (node.go)
- Close page on Goto failure to prevent resource leak (playwright.go)
- Fix teardown order: close context before browser (playwright.go)
- Clean up resources on NewPage failure (interactive.go)
- Spawn cleanup goroutine on context cancellation in both constructors

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-03-02 04:54:00 +00:00
steveandClaude Opus 4.6 1b95d12890 feat: add steps parameter to MouseMove for smooth drag gestures
CI / test (pull_request) Successful in 47s
CI / vet (pull_request) Successful in 1m34s
CI / build (pull_request) Successful in 1m37s
Makes MouseMove accept an optional steps variadic parameter that maps
to Playwright's MouseMoveOptions.Steps, generating intermediate
mousemove events for human-like drag behavior.

Closes #81

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-28 16:23:32 +00:00
steveandClaude Opus 4.6 00ff7ea830 feat: add MouseDown/MouseUp methods to InteractiveBrowser
CI / test (pull_request) Successful in 1m11s
CI / vet (pull_request) Successful in 1m28s
CI / build (pull_request) Successful in 1m30s
Enables drag operations (mousedown → mousemove → mouseup) needed for
slider captchas and other drag-based interactions.

Closes #79

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-28 15:35:36 +00:00
steve d35d144fa2 Merge pull request 'feat: promote headless page to InteractiveBrowser mid-session' (#78) from feature/76-promote-to-interactive into main
CI / vet (push) Successful in 1m8s
CI / build (push) Successful in 1m10s
CI / test (push) Successful in 1m10s
Reviewed-on: #78
2026-02-24 02:29:07 +00:00
steveandClaude Opus 4.6 e0da88b9b0 feat: add PromoteToInteractive and DemoteToDocument for mid-session page transfer
CI / build (pull_request) Successful in 29s
CI / test (pull_request) Successful in 36s
CI / vet (pull_request) Failing after 6m18s
Allow transferring ownership of a Playwright page between Document and
InteractiveBrowser modes without tearing down the browser. This enables
handing a live page to a human (e.g. for captcha solving) and resuming
scraping on the same page afterward.

Closes #76

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-24 02:27:42 +00:00
steve 39371dc261 Merge pull request 'fix: secure field lost in cookie round-trip & batch AddCookies failure' (#77) from fix/75-cookie-secure-field-roundtrip into main
CI / vet (push) Successful in 1m9s
CI / test (push) Successful in 1m10s
CI / build (push) Successful in 1m11s
Reviewed-on: #77
2026-02-24 02:14:43 +00:00
steveandClaude Opus 4.6 debf0ee2ed fix: map Secure field in cookie conversions and add per-cookie error handling
CI / vet (pull_request) Successful in 1m7s
CI / build (pull_request) Successful in 1m7s
CI / test (pull_request) Successful in 1m10s
The Secure field was dropped in both Playwright<->internal cookie
conversion functions, causing cookies with __Secure-/__Host- prefixes
to be rejected by Chromium. Additionally, batch AddCookies meant one
invalid cookie would fail browser creation entirely.

Changes:
- Map Secure field in cookieToPlaywrightOptionalCookie and
  playwrightCookieToCookie
- Add cookies one-by-one with slog.Warn on failure instead of
  failing the entire batch
- Add unit tests for both conversion functions

Closes #75

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-24 02:13:19 +00:00
steve 01aea52533 Merge pull request 'fix: randomize hardware fingerprints across sessions' (#74) from feature/71-randomize-fingerprints into main
CI / vet (push) Successful in 48s
CI / test (push) Successful in 53s
CI / build (push) Successful in 57s
Reviewed-on: #74
2026-02-24 01:39:27 +00:00
steveandClaude Opus 4.6 4772b153b8 fix: randomize hardware fingerprint values across browser sessions
CI / build (pull_request) Successful in 30s
CI / vet (pull_request) Successful in 2m17s
CI / test (pull_request) Successful in 2m21s
Replace static stealthChromiumScripts and stealthFirefoxScripts slices
with builder functions that accept hardware profile structs. Each browser
session now randomly selects from a pool of 6 realistic profiles per
engine, and Chromium connection stats receive per-session jitter (±20ms
RTT, ±2 Mbps downlink). This prevents anti-bot systems from correlating
sessions via identical WebGL, connection, mozInnerScreen, and
hardwareConcurrency fingerprints.

Closes #71

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-24 01:38:14 +00:00
steve 8eb69c1dee Merge pull request 'fix: default viewport and engine-aligned User-Agent' (#73) from fix/70-default-viewport-ua-alignment into main
CI / vet (push) Successful in 1m12s
CI / build (push) Successful in 1m12s
CI / test (push) Successful in 1m13s
Reviewed-on: #73
2026-02-24 01:29:37 +00:00
steveandClaude Opus 4.6 6647e4f63d fix: set default viewport for NewBrowser and align User-Agent with engine
CI / vet (pull_request) Successful in 1m6s
CI / build (pull_request) Successful in 1m11s
CI / test (pull_request) Successful in 1m11s
NewBrowser previously had no viewport (strong headless signal) and used a
Firefox User-Agent unconditionally, even for Chromium instances (detectable
mismatch).

Add per-engine UA constants (DefaultFirefoxUserAgent, DefaultChromiumUserAgent)
and auto-select the matching UA in initBrowser when the caller hasn't set one
explicitly. Keep DefaultUserAgent as a backward-compatible alias.

Add 1920x1080 default viewport to NewBrowser (most common desktop resolution).
NewInteractiveBrowser keeps its existing 1280x720 default but also gains
engine-aware UA selection.

Closes #70

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-24 01:28:09 +00:00
steve ff1d6c491a Merge pull request 'fix: split stealth scripts by browser engine, add Firefox stealth' (#72) from fix/69-firefox-stealth-scripts into main
CI / vet (push) Successful in 1m3s
CI / build (push) Successful in 1m9s
CI / test (push) Successful in 1m9s
Reviewed-on: #72
2026-02-24 01:23:25 +00:00
steveandClaude Opus 4.6 34161209de fix: split stealth init scripts by browser engine and add Firefox stealth
CI / vet (pull_request) Successful in 1m59s
CI / build (pull_request) Successful in 2m1s
CI / test (pull_request) Successful in 2m1s
The stealth system previously injected all 12 init scripts unconditionally
into every browser engine. Chromium-specific scripts (window.chrome stubs,
ANGLE WebGL strings, CDP cleanup, HeadlessChrome UA strip) were no-ops or
actively suspicious on Firefox, while Firefox-specific headless vectors
were unaddressed.

Split stealthInitScripts into three categories:
- stealthCommonScripts (4): webdriver, outerWidth/Height, permissions, Notification
- stealthChromiumScripts (8): existing Chromium-specific scripts
- stealthFirefoxScripts (5): new Firefox-specific stealth:
  - navigator.webdriver getOwnPropertyDescriptor hardening
  - WebGL renderer spoof with Mesa/Intel strings
  - mozInnerScreenX/Y non-zero spoof
  - navigator.hardwareConcurrency normalization
  - PDF.js plugin list override

browser_init.go now selects common + engine-specific scripts based on
opt.Browser. Tests updated with per-category validation and cross-
contamination checks.

Closes #69

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-24 01:20:40 +00:00
steve 3cc528a766 Merge pull request 'feature: add PizzINT site extractor with HTTP API' (#67) from feature/pizzint-site-extractor into main
CI / vet (push) Successful in 31s
CI / build (push) Successful in 1m8s
CI / test (push) Successful in 1m9s
Reviewed-on: #67
2026-02-22 05:52:56 +00:00
steveandClaude Opus 4.6 c1c1acdb00 feature: add PizzINT (Pentagon Pizza Index) site extractor
CI / vet (pull_request) Successful in 1m7s
CI / build (pull_request) Successful in 1m9s
CI / test (pull_request) Successful in 1m9s
Adds a new site extractor for pizzint.watch, which tracks pizza shop
activity near the Pentagon as an OSINT indicator. The extractor fetches
the dashboard API and exposes DOUGHCON levels, restaurant activity, and
spike events.

Includes a CLI tool with an HTTP server mode (--serve) for embedding
the pizza status in dashboards or status displays.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-22 05:45:55 +00:00
steve 710d75259e Merge pull request 'fix: use structural selectors for DDG weather advisory handling' (#65) from fix/weather-advisory-selectors into main
CI / build (push) Successful in 29s
CI / vet (push) Successful in 1m1s
CI / test (push) Successful in 1m2s
Reviewed-on: #65
2026-02-20 18:23:54 +00:00
steveandClaude Opus 4.6 8c2848246b fix: use structural selectors for DDG weather to handle advisory banners
CI / build (pull_request) Successful in 1m11s
CI / vet (pull_request) Successful in 1m12s
CI / test (pull_request) Successful in 1m17s
The weather extractor used positional CSS selectors (div:first-child,
div:nth-child(2)) to locate the header and hourly container within the
widget section. When DuckDuckGo inserts advisory banners (e.g. wind
advisory), the extra div shifts positions and breaks extraction of
current temp, hourly data, humidity, and wind.

Replace with structural selectors:
- div:not(:has(ul)) for the header (first div without a list)
- div:has(> ul) for the hourly container (div with direct ul child)

These match elements by their content structure rather than position,
so advisory banners no longer break extraction.

Fixes #64

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-20 18:22:53 +00:00
steve 8a2de65e31 Merge pull request 'feat: add RemoveHidden option for display:none element stripping' (#63) from feature/readability-remove-hidden into main
CI / build (push) Successful in 28s
CI / test (push) Successful in 47s
CI / vet (push) Successful in 49s
Reviewed-on: #63
2026-02-20 14:10:58 +00:00
steveandClaude Opus 4.6 65cf6b027f feat: add RemoveHidden option to strip display:none elements before extraction
CI / vet (pull_request) Successful in 34s
CI / test (pull_request) Successful in 1m1s
CI / build (pull_request) Successful in 1m5s
When RemoveHidden is true, JavaScript is evaluated on the live page to
remove all elements with computed display:none before readability
extraction. This defends against anti-scraping honeypots that embed
prompt injections in hidden DOM elements.

The implementation uses an optional pageEvaluator interface so that the
concrete document (backed by Playwright) supports it while the Document
interface remains unchanged.

Closes #62

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-20 14:06:17 +00:00
steveandClaude Opus 4.6 c1a5814732 feat: add ReadabilityWithOptions for DOM cleanup before extraction
CI / build (pull_request) Successful in 46s
CI / test (pull_request) Successful in 48s
CI / vet (pull_request) Successful in 1m50s
Sites with infinite scroll (e.g. The Verge) load additional articles
into the DOM, which get included in readability extraction. Add
ReadabilityOptions.RemoveSelectors to strip elements by CSS selector
before parsing, avoiding the need to reimplement the readability
pipeline downstream.

Closes #60

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-19 01:09:28 +00:00
steveandClaude Opus 4.6 ce95fb1d89 fix: enhance stealth mode with additional anti-detection measures
CI / build (pull_request) Successful in 47s
CI / vet (pull_request) Successful in 46s
CI / test (pull_request) Successful in 49s
Add 7 new init scripts to cover WebGL fingerprinting, missing Chrome
APIs, permissions behavior, CDP artifacts, and HeadlessChrome UA string.
Enable Chromium's new headless mode (Channel: "chromium") when stealth
is active to use the full UI layer that is harder to detect.

Closes #58

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-17 22:45:12 +00:00
steveandClaude Opus 4.6 e94665ff25 feature: add stealth mode, launch args, and init scripts to BrowserOptions
CI / vet (pull_request) Successful in 1m18s
CI / build (pull_request) Successful in 1m22s
CI / test (pull_request) Successful in 1m28s
Add anti-bot-detection evasion support to reduce blocking by sites like
archive.ph. Stealth mode is enabled by default for all browsers and applies
common evasions: navigator.webdriver override, plugin/mimeType spoofing,
window.chrome stub, and outerWidth/outerHeight fixes. For Chromium,
--disable-blink-features=AutomationControlled is also added.

New BrowserOptions fields:
- Stealth *bool: toggle stealth presets (default true)
- LaunchArgs []string: custom browser launch arguments
- InitScripts []string: JavaScript injected before page scripts

Closes #56

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-17 20:10:58 +00:00
steve e8f4d64eb9 Merge pull request 'fix: update weather selectors to match DDG's actual DOM' (#54) from fix/weather-selector-dom-mismatch into main
CI / build (push) Successful in 36s
CI / test (push) Successful in 51s
CI / vet (push) Successful in 51s
Reviewed-on: #54
2026-02-15 23:07:10 +00:00
steveandClaude Opus 4.6 a32f57ec92 fix: update weather extractor selectors to match DuckDuckGo's actual DOM
CI / build (pull_request) Successful in 30s
CI / vet (pull_request) Successful in 45s
CI / test (pull_request) Successful in 48s
DuckDuckGo's weather widget uses randomized CSS module class names that
don't match the BEM-style selectors the extractor was using. Replace all
class-based selectors with structural and attribute-based selectors:

- Identify widget via article:has(img[src*='weatherkit'])
- Use positional selectors (div:first-child, p:first-of-type, etc.)
- Extract icon hints from img[alt] attributes
- Parse precipitation from span > span structure
- Derive CurrentTemp from first hourly entry (no standalone element)
- Derive HighTemp/LowTemp from first daily forecast entry
- Use text-matching for Humidity/Wind labels

Fixes #53

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 23:00:44 +00:00
steve cff4713282 Merge pull request 'feature: add hourly forecast, precipitation, and icon hints to weather extractor' (#52) from feature/weather-hourly-precip-icons into main
CI / vet (push) Successful in 1m5s
CI / build (push) Successful in 1m6s
CI / test (push) Successful in 1m8s
Reviewed-on: #52
2026-02-15 21:23:35 +00:00
steveandClaude Opus 4.6 469171da9c feature: add hourly forecast, precipitation, and icon hints to weather extractor
CI / build (pull_request) Successful in 30s
CI / vet (pull_request) Successful in 46s
CI / test (pull_request) Successful in 49s
Add HourlyForecast struct and Hourly field to WeatherData for hourly
temperature/condition data. Add Precipitation (int, -1 if unavailable)
and IconHint (from aria-label/title/alt attributes) to both DayForecast
and HourlyForecast. This enables downstream consumers like mort to
replace inline DuckDuckGo scraping with a single GetWeather() call.

Closes #51

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 21:22:04 +00:00
steveandClaude Opus 4.6 df934a0521 feature: add Bambu Lab firmware version extractor
CI / build (pull_request) Successful in 30s
CI / vet (pull_request) Successful in 48s
CI / test (pull_request) Successful in 49s
Extract firmware information from Bambu Lab's firmware download pages
by parsing the __NEXT_DATA__ JSON blob embedded in the page. Supports
all printer models (X1, P1, A1, A1 mini, H2D, H2S, P2S, X1E, H2D Pro).

Provides GetLatestFirmware() and GetAllFirmware() methods that return
version, release date, release notes, download URL, and MD5 checksum.

Closes #45

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 20:21:06 +00:00
steveandClaude Opus 4.6 c2768e2b05 feature: add IMDB movie/TV extractor
CI / test (pull_request) Successful in 46s
CI / vet (pull_request) Successful in 47s
CI / build (pull_request) Successful in 1m18s
Add sites/imdb package with GetMovie() and Search() methods. Extracts
title, year, rating, votes, runtime, genres, director, cast, plot,
poster, and box office data. Uses JSON-LD parsing with DOM fallback.
Supports Movie, TVSeries, and TVMiniSeries types.

Closes #30

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 16:54:30 +00:00
steveandClaude Opus 4.6 de0a065923 feature: add recipe extractor with JSON-LD and DOM parsing
CI / build (pull_request) Successful in 57s
CI / vet (pull_request) Successful in 1m2s
CI / test (pull_request) Successful in 1m5s
Add sites/recipe package with ExtractRecipe() that works on any recipe
URL. Parses JSON-LD structured data (@type: Recipe) first, with DOM
fallback. Handles @graph containers, arrays, HowToStep objects, ISO
8601 durations, and various author/yield/image formats.

Closes #29

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 16:52:28 +00:00
steveandClaude Opus 4.6 b1137f2ebc feature: add Steam Store game price extractor
CI / vet (pull_request) Successful in 1m24s
CI / build (pull_request) Successful in 1m24s
CI / test (pull_request) Successful in 1m28s
Add sites/steam package with GetGamePrice() and SearchGames() methods.
Handles regular prices, discounted games, and free-to-play titles.
Includes age gate bypass logic and currency detection.

Closes #28

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 16:50:27 +00:00
steveandClaude Opus 4.6 349b1b9c6b feature: add CoinGecko cryptocurrency price extractor
CI / build (pull_request) Successful in 46s
CI / vet (pull_request) Successful in 1m20s
CI / test (pull_request) Successful in 1m23s
Add sites/coingecko package with GetPrice() method that extracts
structured crypto price data (name, symbol, price, 24h/7d change,
market cap, volume, 24h high/low) from CoinGecko coin pages.

Includes mock-based tests and parseLargeNumber helper for T/B/M suffixes.

Closes #27

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 16:47:53 +00:00
steve 461b704792 feature: add DuckDuckGo weather and stock widget extractors
CI / vet (pull_request) Successful in 29s
CI / build (pull_request) Successful in 46s
CI / test (pull_request) Successful in 48s
Add weather.go with GetWeather() for extracting structured weather data
(location, temp, conditions, forecast) and stock.go with GetStockQuote()
and GetStockChart() for stock data extraction and chart screenshots.

Both include mock-based tests. CSS selectors may need tuning against
the live site since DuckDuckGo's React-rendered widgets use dynamic
class names.

Closes #25, #26
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 16:40:53 +00:00
steve 198906946b test: add mock-based site extractor test infrastructure
CI / vet (pull_request) Successful in 1m5s
CI / build (pull_request) Successful in 1m6s
CI / test (pull_request) Successful in 1m6s
Create exported extractortest package with MockBrowser, MockDocument,
and MockNode that support selector-based responses for testing site
extractors without a real browser.

Add extraction tests for DuckDuckGo (result parsing, empty results, no
links, full search flow) and Powerball (drawing parsing, next drawing
parsing with billion/million, error cases, full GetCurrent flow).

Closes #21
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 16:37:58 +00:00
steve 963696cd62 enhance: thread-safe CookieJar, SameSite cookie attr, dynamic Google countries
CI / vet (pull_request) Successful in 40s
CI / build (pull_request) Successful in 1m22s
CI / test (pull_request) Successful in 1m28s
- Wrap staticCookieJar in struct with sync.RWMutex for thread safety
- Add SameSite field to Cookie struct with Strict/Lax/None constants
- Update Playwright cookie conversion functions for SameSite
- Replace hardcoded 4-country switch with dynamic country code generation

Closes #20, #22, #23
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 16:34:54 +00:00
steve a9711ce904 fix: surface parsing errors instead of silently discarding them
CI / vet (pull_request) Successful in 1m10s
CI / build (pull_request) Successful in 1m21s
CI / test (pull_request) Successful in 1m28s
Return errors for required fields (ID, price) and log warnings for
optional fields (title, description, unit price) across all site
extractors instead of silently discarding them with _ =.

Closes #24
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 16:31:56 +00:00
steveandClaude Opus 4.6 132817144e refactor: deduplicate numericOnly and DuckDuckGo result extraction
CI / build (pull_request) Successful in 29s
CI / vet (pull_request) Successful in 1m1s
CI / test (pull_request) Successful in 1m4s
- Extract identical numericOnly inline functions from powerball and
  megamillions into shared sites/internal/parse.NumericOnly with tests
- Extract duplicated DuckDuckGo result parsing from Search() and
  GetResults() into shared extractResults() helper

Closes #13, #14

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 16:26:54 +00:00
steveandClaude Opus 4.6 097b2e12c7 fix: consolidate user-agent strings into DefaultUserAgent constant
CI / build (pull_request) Successful in 44s
CI / test (pull_request) Successful in 46s
CI / vet (pull_request) Successful in 1m28s
Define DefaultUserAgent (Firefox/147.0) in playwright.go and reference
it from NewBrowser, NewInteractiveBrowser, and CLI flags. Previously
three different UA strings existed (two at 142.0, one outdated at 133.0).

Closes #17

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 16:24:44 +00:00
steveandClaude Opus 4.6 328455de32 fix: ShowBrowser merge behavior and consistent browser defaults
CI / vet (pull_request) Successful in 1m49s
CI / build (pull_request) Successful in 1m51s
CI / test (pull_request) Successful in 1m52s
- Change ShowBrowser from bool to *bool so nil means "don't override"
  in mergeOptions(), fixing the bug where it always overwrote the base
- Add Bool() helper for convenient *bool construction
- Align NewInteractiveBrowser default from Chromium to Firefox to match
  NewBrowser
- Update README example and CLI flags for the *bool change

Closes #15, #16

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 16:22:49 +00:00
steveandClaude Opus 4.6 769b870a17 fix: check Cookies() error and use context-aware sleep
CI / build (pull_request) Successful in 46s
CI / vet (pull_request) Successful in 47s
CI / test (pull_request) Successful in 1m22s
- playwright.go: check error from page.Context().Cookies() before
  iterating over results, preventing silent failures
- archive.go: replace time.Sleep(5s) with context-aware select using
  time.After, allowing the operation to be cancelled promptly

Closes #7, #18

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 16:19:49 +00:00
steveandClaude Opus 4.6 e5e0db85e8 fix: use merged flags in archive cmd and move defer after error checks
CI / vet (pull_request) Successful in 29s
CI / build (pull_request) Successful in 32s
CI / test (pull_request) Successful in 57s
- Fix archive cmd passing only archive-specific Flags instead of the
  merged flags variable that includes browser flags (#8)
- Move defer DeferClose() after error checks in 6 locations to prevent
  calling Close on nil values (#19):
  - sites/duckduckgo/cmd/duckduckgo/main.go
  - sites/duckduckgo/duckduckgo.go
  - sites/google/cmd/google/main.go
  - sites/wegmans/cmd/wegmans/main.go
  - sites/wegmans/wegmans.go
  - sites/aislegopher/aislegopher.go

Closes #8, #19

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 16:17:38 +00:00
steveandClaude Opus 4.6 a12c9f7cb6 fix: propagate errors from DuckDuckGo search and GetResults
CI / test (pull_request) Failing after 6m12s
CI / vet (pull_request) Failing after 6m12s
CI / build (pull_request) Failing after 6m15s
- Change SearchPage.GetResults() to return ([]Result, error) so ForEach
  errors are no longer silently discarded
- Fix Search() to return the ForEach error instead of nil
- Update cmd caller to check GetResults() errors

Closes #5, #6

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 16:16:04 +00:00
steveandClaude Opus 4.6 b4e462a6b4 fix: prevent panic on short article content in archive cmd
CI / vet (pull_request) Successful in 1m6s
CI / build (pull_request) Successful in 1m7s
CI / test (pull_request) Successful in 1m8s
Add length check before slicing article.Content[:32], matching the
safe truncation pattern already used in cmd/browser/main.go.

Closes #9

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 16:14:32 +00:00
steveandClaude Opus 4.6 6c68062e56 fix: add nil guards to prevent nil-pointer panics
CI / test (pull_request) Successful in 46s
CI / build (pull_request) Successful in 47s
CI / vet (pull_request) Successful in 59s
- document.go: check if resp is nil before calling resp.Status() in
  Refresh(), since Playwright's Reload() can return a nil response
- archive.go: check SelectFirst() results for nil before calling
  Type() and Click(), preventing panics when DOM elements are missing

Closes #10, #11

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 16:13:43 +00:00
steveandClaude Opus 4.6 6e94bfe10f fix: eliminate XSS vulnerability in SetAttribute by using Playwright arg passing
CI / build (pull_request) Successful in 47s
CI / test (pull_request) Successful in 48s
CI / vet (pull_request) Successful in 1m1s
Replace string interpolation in SetAttribute with Playwright's Evaluate
argument passing mechanism. This structurally eliminates the injection
surface — arbitrary name/value strings are safely passed as JavaScript
arguments rather than interpolated into the expression string.

The vulnerable escapeJavaScript helper (which only escaped \ and ') is
removed since it is no longer needed.

Closes #12

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 16:12:46 +00:00
steveandClaude Opus 4.6 49f294e884 docs: add README.md and CLAUDE.md
CI / test (push) Successful in 32s
CI / vet (push) Successful in 45s
CI / build (push) Successful in 46s
Add project documentation:
- README.md with installation, usage examples, API reference, and project structure
- CLAUDE.md with developer guide, architecture overview, conventions, and issue label docs

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-14 11:10:28 -05:00
steveandClaude Opus 4.6 05ca15b165 fix: add go.sum to repository for CI builds
CI / build (push) Successful in 34s
CI / vet (push) Successful in 57s
CI / test (push) Successful in 1m0s
The go.sum file was not tracked, causing CI to fail with
"missing go.sum entry" errors during build/test/vet.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-09 14:15:43 -05:00
steveandClaude Opus 4.6 294097c3b6 fix: use setup-go@v3 (latest available on gitea.com mirror)
CI / vet (push) Failing after 26s
CI / build (push) Failing after 32s
CI / test (push) Failing after 36s
The gitea.com/actions/setup-go mirror only has tags up to v3.
v3 supports go-version-file which is all we need.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-09 14:13:46 -05:00
steveandClaude Opus 4.6 022e002f98 ci: use gitea.com action mirrors instead of github.com
CI / test (push) Failing after 15s
CI / vet (push) Failing after 15s
CI / build (push) Failing after 18s
GitHub is returning 500 errors for actions/checkout and actions/setup-go.
Switch to Gitea's own mirrors at gitea.com/actions/ to avoid the dependency.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-09 14:09:46 -05:00
steveandClaude Opus 4.6 51ce639994 ci: re-trigger workflow after transient GitHub 500 error
CI / test (push) Failing after 10s
CI / build (push) Failing after 2m2s
CI / vet (push) Failing after 2m2s
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-09 14:06:39 -05:00
steveandClaude Opus 4.6 cb2ed10cfd refactor: restructure API, deduplicate code, expand test coverage
CI / build (push) Failing after 2m4s
CI / test (push) Failing after 2m6s
CI / vet (push) Failing after 2m19s
- Extract shared DeferClose helper, removing 14 duplicate copies
- Rename PlayWright-prefixed types to cleaner names (BrowserOptions,
  BrowserSelection, NewBrowser, etc.)
- Rename fields: ServerAddress, RequireServer (was DontLaunchOnConnectFailure)
- Extract shared initBrowser/mergeOptions into browser_init.go,
  deduplicating ~120 lines between NewBrowser and NewInteractiveBrowser
- Remove unused locator field from document struct
- Add tests for all previously untested packages (archive, aislegopher,
  wegmans, useragents, powerball) and expand existing test suites
- Add MIGRATION.md documenting all breaking API changes

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-09 13:59:47 -05:00
steveandClaude Opus 4.6 e7b7e78796 fix: bug fixes, test coverage, and CI workflow
CI / vet (push) Failing after 15s
CI / build (push) Failing after 30s
CI / test (push) Failing after 36s
- Fix Nodes.First() panic on empty slice (return nil)
- Fix ticker leak in archive.go (create once, defer Stop)
- Fix cookie path matching for empty and root paths
- Fix lost query params in google.go (u.Query().Set was discarded)
- Fix type assertion panic in useragents.go
- Fix dropped date parse error in powerball.go
- Remove unreachable dead code in megamillions.go and powerball.go
- Simplify document.go WaitForNetworkIdle, remove unused root field
- Remove debug fmt.Println calls across codebase
- Replace panic(err) with stderr+exit in all cmd/ programs
- Fix duckduckgo cmd: remove useless defer, return error on bad safesearch
- Fix archive cmd: ToConfig returns error instead of panicking
- Add 39+ unit tests across 6 new test files
- Add Gitea Actions CI workflow (build, test, vet in parallel)

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-09 11:14:19 -05:00
steveandClaude Opus 4.6 52a9cb585d feat: add InteractiveBrowser API for remote browser control
Exposes low-level mouse, keyboard, screenshot, navigation, and cookie
extraction APIs via a new InteractiveBrowser interface. Designed for
interactive browser proxy sessions where direct page control is needed.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-09 02:58:00 -05:00
steve 868acfae40 Add context support to Playwright browser initialization
Refactored Playwright initialization to ensure context propagation. Updated `NewPlayWrightBrowser` and related methods to accept `context.Context` for better cancellation and timeout handling. Improved error resilience and concurrency during browser setup.
2025-10-28 00:24:19 -04:00
steve 82fce5a200 Handle unit suffix in price parsing and add logging
Refined price parsing logic to strip trailing periods from units (e.g., "lb." -> "lb") for better handling. Added logging for debugging extracted response data.
2025-10-20 22:36:20 -04:00
steve 5fe7313fa4 Refine status check logic when handling document requests in Playwright 2025-10-12 20:17:04 -04:00
steve 39c2c7d37a Add UseLocalOnly flag to connection options in Playwright logic 2025-10-12 00:17:11 -04:00
steve e32a6fa791 Add UseLocalOnly option to Playwright connection logic
Introduced the `UseLocalOnly` option to prevent connections to a remote Playwright server and enforce usage of the local server. Updated relevant connection logic to respect this new option.
2025-10-12 00:10:58 -04:00
steve afa0238758 Restrict Price assignment to unit price with "lb" only 2025-10-11 23:48:09 -04:00
steve 9ae8619f93 Enhance price parsing to handle non-zero unit price
Updated price extraction logic to set `Price` from `UnitPrice` when it is non-zero, ensuring more accurate parsing.
2025-10-11 23:34:41 -04:00
steve f4caef22b0 Add timeout option to Playwright server connection
Introduced a 30-second timeout for connecting to the Playwright server. Added logging for connection attempts to improve debugging and enhance connection reliability.
2025-10-10 20:25:27 -04:00
steve 9947cae947 Refine selectors and enhance price parsing with logging
Adjusted HTML selectors for improved compatibility and updated price parsing logic to handle additional formats. Added logging to provide better debugging insights during price extraction.
2025-10-10 14:42:06 -04:00
steve d0fffb0411 Add warning log for Playwright server connection failure
Introduce a warning log to notify when failing to connect to the Playwright server, followed by a fallback to launching a local browser.
2025-08-29 01:39:40 -04:00
steve 8b4e43c40f Add DontLaunchOnConnectFailure and refine server connection logic
Introduced the `DontLaunchOnConnectFailure` option to prevent browser launch on connection failure when connecting to a Playwright server. Enhanced environment variable handling for server address based on browser type, improving flexibility and reliability in connection scenarios.
2025-08-29 01:38:00 -04:00
steve 6f4ca22b6a Update Firefox user agent version in PlayWrightBrowserOptions
Adjusted the default `UserAgent` in `PlayWrightBrowserOptions` to reflect the latest Firefox version (142.0) for improved compatibility and accuracy.
2025-08-29 00:25:45 -04:00
steve 8aee8f0502 Add support for connecting to a remote Playwright server
Introduced `PlayWrightServerAddress` to `PlayWrightBrowserOptions`, allowing the browser to connect to a remote Playwright server if specified. Defaults to the `PLAYWRIGHT_SERVER_ADDRESS` environment variable. Updated initialization logic to handle both local launches and remote connections seamlessly.
2025-08-29 00:25:23 -04:00
steve 39453288ce Add OpenSearch and SearchPage functionality for DuckDuckGo
Introduced the `OpenSearch` method and `SearchPage` interface to streamline search operations and allow for loading more results dynamically. Updated dependencies and modified the DuckDuckGo CLI to utilize these enhancements.
2025-03-18 02:42:50 -04:00
steve 7c0e44a22f Add viewport dimensions and dark mode support
This commit introduces optional viewport dimensions and dark mode support to the PlayWrightBrowserOptions struct and its usage. It ensures more control over browser display settings and improves flexibility when configuring browser contexts. Additionally, visibility checking logic in SetHidden was refined to avoid redundant operations.
2025-03-15 00:46:02 -04:00
steve 0f9f6c776d Rename SetVisible to SetHidden for clearer semantic meaning
The method and its implementation now align with setting an element's "hidden" property instead of "visible." This change improves code clarity and consistency with expected behavior.
2025-03-03 23:39:37 -05:00
steve 62cb6958fa Add SetVisible and SetAttribute methods to Node interface
This commit introduces two new methods, SetVisible and SetAttribute, to the Node interface. These methods allow toggling element visibility and setting attributes dynamically. Additionally, a helper function, escapeJavaScript, was added to ensure proper escaping of JavaScript strings.
2025-03-03 23:31:51 -05:00
steve 964a98a5a8 Handle commands without automatic reaction responses
Introduce `ErrCommandNoReactions` to allow commands to opt out of success reactions. Adjust bot behavior to respect this error and prevent reactions when applicable, ensuring cleaner and more controlled responses. Add error handling and safeguard workers against panics.
2025-01-22 21:06:07 -05:00
steve 81ea656332 Add unit price and unit parsing for items
This update enhances the `Item` structure to include `UnitPrice` and `Unit` fields. Additional logic is implemented to extract and parse unit pricing details from the HTML, improving data accuracy and granularity.
2025-01-21 19:42:25 -05:00
steve 6de455b1bd Add price extraction and validate URL structure in parsers
Added price field to Item struct in AisleGopher and implemented logic to extract price data. Updated Wegmans parser to validate URL structure by ensuring the second segment is "product". These changes improve data accuracy and error handling.
2025-01-20 13:00:59 -05:00
steve f37e60dddc Add Wegmans module to fetch item details and prices
Introduce functionality to retrieve item details, including name and price, from Wegmans using a browser-based scraper. This includes a CLI tool to execute searches and robust error handling for URL validation and browser interactions.
2025-01-20 12:28:29 -05:00
steve e8de488d2b Update CSS selector for extracting titles in DuckDuckGo parser
Replaced the overly complex CSS selector with a simplified "h2" selector for extracting titles. This change improves maintainability and ensures accurate title extraction from the updated DOM structure.
2025-01-16 21:37:38 -05:00
steve 67a3552747 Add DuckDuckGo integration for search functionality
Implemented a DuckDuckGo search module with configurable SafeSearch and regional settings. Added a CLI tool to perform searches via DuckDuckGo using browser automation, supporting flags for customization.
2025-01-16 20:45:37 -05:00
steve eec94ec708 Reorder imports in main.go for better organization.
Moved the local package import to align with standard Go import grouping conventions. This improves code readability and maintains a consistent structure.
2025-01-16 20:45:23 -05:00
steve 691ae400d1 Add Google search integration with CLI support
Introduce a Google search integration, including a Go package for performing searches with configurable parameters (e.g., language, region) and a CLI tool for executing search queries. Refactor archive CLI import ordering for consistency.
2025-01-16 16:56:05 -05:00
steve 2ca2bb0742 close playwright instance on browser close 2025-01-01 22:48:12 -05:00
steve 36707dec17 added useragents to go-extractor 2024-12-24 12:15:48 -05:00
steve 276b7ad38d removed some unused files 2024-12-23 18:24:14 -05:00
steve 567a9f9212 added archive, megamillions, and powerball site logic 2024-12-23 03:18:50 -05:00
steve 5e924eb3f9 changed browser api to return pages that can be acted on, not strictly contents 2024-12-17 23:16:13 -05:00
steve 23334991b1 make screenshot update cookies 2024-12-14 00:50:25 -05:00
steve a51f8200ea added screenshots 2024-12-09 13:51:00 -05:00
steve cbd6682257 initial commit 2024-12-07 03:53:46 -05:00