…unit tests
With the 6h hang fixed, the Test Suite job now runs to completion and exposed
a pre-existing, broadly-broken suite: 100 failed / 208 passed. This restores it
to green (283 passed, 43 deselected) by scoping the unit job to genuine unit
tests and fixing real bugs uncovered along the way.
Scope CI to true unit tests:
- conftest: auto-mark tests/graphs/* (except the mocked abstract_graph_test) as
`integration`. These run full pipelines against real LLM providers, remote
search engines, or optional backends (OpenAI/Ollama/Mistral/Fireworks/Ernie),
so they need API keys / network / extra packages and are not unit tests. The
CI selector `-m "unit or not integration"` now deselects them.
Dependencies:
- add `ddgs` (langchain-community's DuckDuckGoSearchResults now imports it).
- add `selenium` and `pandas` to dev-deps so the mocked selenium-backend and
CSV fetch unit tests can run.
Genuine source bug fixes:
- docloaders/chromium.py: close the browser in a `finally` (was leaked on
failure); honor `requires_js_support` in `scrape()`; map the selenium backend
to `ascrape_undetected_chromedriver` in lazy/alazy_load (was calling a
nonexistent `ascrape_selenium`); validate browser_name before the retry loop;
hoist the optional `Malenia` import to module scope.
- nodes/fetch_node.py: fix UnboundLocalError on `parsed_content`/`document`;
default timeout to 30s when node_config is None (only explicit None disables);
route `txt` input to the local-source handler.
- utils/copy.py: make `safe_deepcopy` a real recursive deep copy with a memo
dict so circular references no longer raise DeepCopyError and object
attributes are actually deep-copied.
- utils/proxy_rotation.py: parse scheme-less `host:port` servers correctly and
route the `broker` keyword to proxy search; fix the error message.
- utils/research_web.py: slice DuckDuckGo results to max_results.
- docloaders/plasmate.py: hoist ChromiumLoader import to module scope.
- graphs/abstract_graph.py: raise a clear error when a model's provider cannot
be determined (was a confusing KeyError).
Stale tests updated to assert current correct behavior (no assertions weakened):
chromium mocks, fetch fixtures, deepcopy/omni, generate_answer keys,
models_tokens limits, proxy/research_web/sys_dynamic_import, plasmate,
cleanup_html, robot/search nodes, script_creator_multi.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Problem
Every Test Suite run on pre/beta/main is being cancelled after 6 hours (The job has exceeded the maximum execution time of 6h0m0s). The run hangs at tests/test_chromium.py::test_scrape_method_retry_logic → the next test, test_ascrape_playwright_scroll_invalid_params, never returns.
Root cause
In ChromiumLoader.ascrape_playwright_scroll the timeout guard was:
When timeout=0, 0 and ... short-circuits to 0 (falsy), so the ValueError is never raised. Execution falls through to async_playwright() → page.goto(url), a real network navigation to http://example.com. The unit test test_ascrape_playwright_scroll_invalid_params passes timeout=0 expecting the ValueError, so instead of asserting it hangs on the live browser call until the 6h CI limit kills the whole job.
Fix
Use an explicit is not None check so timeout=0 is correctly treated as "set" and rejected:
Verification
tests/test_chromium.py::test_ascrape_playwright_scroll_invalid_params now passes in ~7s instead of hanging.
🤖 Generated with Claude Code