[py] improve how tests are run against the grid server - #16851
Conversation
PR Compliance Guide 🔍Below is a summary of compliance checks for this PR:
Compliance status legend🟢 - Fully Compliant🟡 - Partial Compliant 🔴 - Not Compliant ⚪ - Requires Further Human Verification 🏷️ - Compliance label |
|||||||||||||||||||||||||||
PR Code Suggestions ✨Explore these optional code suggestions:
|
||||||||||||||||||||||
cgoldberg
left a comment
There was a problem hiding this comment.
LGTM besides the tiny change I suggested. Thanks.
09a55c2 to
de35dbc
Compare
* [py] run BiDi tests against the Grid server
Add test-<browser>-remote-bidi targets for chrome and firefox, combining the
BiDi test sources with the grid data/env wiring the other remote suites use.
BIDI_TESTS was excluded from every remote suite glob, so the Python BiDi tests
had never run through Grid's websocket proxy.
No client change was needed: --remote and --bidi are independent code paths,
LocalNode already rewrites webSocketUrl to /session/<id>/se/bidi, and
ProxyNodeWebsockets tunnels it to the node.
Kept out of the test-<browser>-remote aggregate for now, since this is new
coverage. No xfail_remote markers were added: the suite passes except for two
tests that fail identically without --remote (a headless-Chrome
document.hasFocus() artifact, and a pre-existing firefox wheel-scroll timing
flake that fails 3/3 runs locally).
* [py] wire the remote BiDi suite into CI and document it
Add a test-remote-bidi aggregate test_suite alongside test-remote, and a
separate remote-bidi-tests job in ci-python.yml that queries it. Keeping it as
its own job means a red BiDi run cannot redden the established remote job while
this coverage is new.
Document the remote targets and the --remote / --bidi --remote pytest flags in
py/TESTING.md, including the Grid jar prerequisite.
* [py] set target_compatible_with on the remote test suites
The bidi and per-browser suites pass BROWSERS[browser]["target_compatible_with"]
through; the remote ones did not. It is a no-op today because the value is empty
for chrome and firefox, but the divergence would silently drop the platform
constraint the first time a remote suite is added for a browser that has one
(ie, safari, webkitgtk).
* [py] collapse the duplicated xfail_remote and remote-directory guards
The "skip unless --remote" guard was written out three times (driver,
firefox_options, chromium_options) and the xfail_<driver>/xfail_remote marker
dance twice (driver, clean_driver). Extract _skip_unless_remote and
_apply_xfail_markers.
The two marker blocks had drifted apart, so unifying them fixes two latent bugs
in the clean_driver path:
- it did not support the condition kwarg, and passed it straight to
pytest.xfail(), which does not accept it (TypeError)
- neither block popped run before calling pytest.xfail(), so an explicit
run=True raised TypeError as well
The `yield`/`return` after pytest.skip() in both blocks was dead code;
pytest.skip() raises.
Verified against alerts_tests, which exercises all three marker paths
(condition, run=False, plain xfail): 20 passed, 1 skipped, 2 xfailed both
before and after.
* [py] give the remote test suites the COMMON_TAGS their siblings carry
The remote suites set tags = ["no-sandbox", "remote", "<browser>-remote"],
omitting BROWSERS[browser]["tags"] (COMMON_TAGS + the bare browser name) that
every non-remote suite carries. Compose from the sibling expression instead and
keep the two remote markers on top.
browser-test and requires-network are inert here - nothing in .bazelrc*,
.github/, scripts/ or the Rakefile filters on either, and requires-network is
moot anyway because no-sandbox already disables the sandbox. The tag that
matters is the bare browser name: py/TESTING.md documents
bazel test //py/... --test_tag_filters=chrome
and that silently matched no remote target. It now matches all 26 per-browser
remote-bidi targets. Ruby already does this and says why in a comment
(rb/spec/tests.bzl), so this aligns Python with the reference implementation.
The omission was incidental rather than deliberate: the per-browser remote
targets in b1904f8 (#16851) inherited the minimal tag set of the single
test-remote target they replaced, and no rationale for the tag choice is
recorded.
* [py] make the focus and wheel-scroll bidi tests work headed and headless
Both tests read an asynchronous result exactly once, so they raced it.
test_activate_browsing_context asserted that creating a second window takes
focus off the first. Focus is handed over asynchronously, so poll for it. That
alone is not enough: headless Chromium has no window manager and never hands
focus over at all, confirmed by a 5s wait timing out 5/5 runs. So skip in that
case only - gated on the new `headless` fixture, and only after the wait has
actually expired. Headless Firefox does hand focus over and keeps the full
assertions; headed runs still fail loudly if the handover regresses, because the
skip cannot trigger outside headless.
test_wheel_scroll_with_duration spreads a 100px scroll over 500ms and then
asserted pageYOffset == 100 immediately; Firefox was reliably one pixel short.
Wait for the scroll to settle before asserting, keeping the exact assertion
rather than widening it to a tolerance.
Verified per browser and per mode:
- test_activate: chrome headless skips (was failing), chrome headed passes with
full assertions, firefox headless passes with full assertions and 0 skips
- test_wheel_scroll_with_duration: failed 3/3 runs at HEAD, 0/3 after
Both tests exist twice (bidi/ and _bidi/); both copies are updated.
Note: py/test/selenium/webdriver/common/_bidi/input_tests.py has further
pre-existing firefox flakiness not addressed here - test_key_input_with_value_attribute,
test_key_input_special_characters and test_combined_input_actions each failed in
some runs, a different one each time, both before and after this change.
User description
🔗 Related Issues
Splitting this out from #16814 so we can manage it independently
💥 What does this PR do?
chrome-remoteandfirefox-remotetargets with tags that can be filtered onwhich java)🔧 Implementation Notes
💡 Additional Considerations
remote_connection_tests.pyare failing now because they were pointing to the wrong server, and I'm not sure they are testing what we think they are testing. Needs to be fixed, but outside the scope of this PR🔄 Types of changes
PR Type
Enhancement
Description
Refactored remote testing to use
--remoteflag instead of driver selectionAdded support for browser-specific remote test targets (chrome-remote, firefox-remote)
Integrated Bazel-built Java and Grid server with fallback to system/Selenium Manager
Enhanced Server class with configurable java_path and startup_timeout parameters
Marked Firefox-specific tests as xfail_remote to skip when running remotely
Diagram Walkthrough
File Walkthrough
2 files
Refactored remote testing to use --remote flagAdded java_path and startup_timeout configuration2 files
Added data attribute to py_test ruleCreated browser-specific remote test targets with Bazel integration6 files
Marked test as xfail_remoteMarked module as xfail_remote for Firefox-specific APIsMarked module as xfail_remote for Firefox-specific APIsUpdated tests to use Grid server and marked as xfailUpdated fixture to use Grid server command_executorUpdated test to use Grid server command_executor2 files