Skip to content

[py] [dotnet] [java] declare Firefox default preferences in each binding - #18070

Merged
titusfortner merged 1 commit into
SeleniumHQ:trunkfrom
titusfortner:firefox-inline-default-prefs
Sep 23, 2026
Merged

titusfortner merged 1 commit into
SeleniumHQ:trunkfrom
titusfortner:firefox-inline-default-prefs

Conversation

@titusfortner

Copy link
Copy Markdown
Member

🔗 Related Issues

💥 What does this PR do?

  • py and dotnet stop reading third_party/js/selenium/webdriver.json for Firefox profile defaults and declare the supported preferences directly, the way Ruby already does
  • java drops the matching {frozen, mutable} parsing, which never had a file to read

🔧 Implementation Notes

  • The values are the ones Ruby has used since db06ba1; the rest of that file configured the legacy Firefox XPI driver or Firefox versions that no longer exist, which is why Ruby dropped them in e7b4b76
  • Each binding declares them rather than reading one shared file — java has no defaults to share and Ruby would need a new gem data file to read one, so converging would mean staging plumbing in three bindings for five constants; Ruby's profile_spec and the new py unit tests pin the values
  • The frozen/mutable split goes with it, and every preference that survives was already mutable, so nothing that could be overridden before stops being overridable:
    • dotnet — SetPreference no longer throws for the 45 frozen keys, none of which remain
    • py — already flattened both sections into one dict, so no change in what a caller can set
    • java — never had defaults at all; it passed Preferences an empty stub to satisfy a constructor, so that parsing and the constructors taking it go too
    • Ruby — unchanged, it is the reference
  • py keeps declaring startup.homepage_welcome_url rather than deriving it from the homepage, so an existing profile directory is still left untouched; java and dotnet already overwrite that preference themselves and are not touched
  • Only reached when a profile is set explicitly — py and dotnet both default to no profile and let geckodriver generate one

🤖 AI assistance

  • No substantial AI assistance used
  • AI assisted (complete below)
    • Tool(s): Claude Code (Opus 5)
    • What was generated: the cross-binding audit of what still reads the file, the changes, the tests, and this description
    • I reviewed all AI output and can explain the change

💡 Additional Considerations

Consider following up with PR removing unused things in third_party

🔄 Types of changes

  • Cleanup (formatting, renaming)

@selenium-ci selenium-ci added C-py Python Bindings C-dotnet .NET Bindings C-java Java Bindings B-build Includes scripting, bazel and CI integrations labels Sep 23, 2026
@qodo-code-review

Copy link
Copy Markdown
Contributor

PR Summary by Qodo

Inline Firefox default preferences across language bindings

✨ Enhancement 🧪 Tests ⚙️ Configuration changes 🕐 20-40 Minutes

Grey Divider

AI Description

• Inline supported Firefox profile defaults in Python and .NET, removing shared JSON resource
 dependencies.
• Remove Java's unused frozen/mutable parsing and simplify preference construction.
• Add Python regression coverage and clean obsolete build/resource wiring.
Diagram

graph TD
  PyDefaults["Python defaults"] --> PyProfile["Python profile"] --> PyUserJs["Python user.js"]
  DotDefaults[".NET defaults"] --> DotProfile[".NET profile"] --> DotUserJs[".NET user.js"]
  ExistingUserJs["Existing user.js"] --> JavaParser["Java parser"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Generate binding constants from one canonical manifest
  • ➕ Retains a single source of truth across supported bindings.
  • ➕ Reduces the chance of preference values diverging over time.
  • ➖ Requires generation and packaging plumbing for Python, .NET, Java, and Ruby.
  • ➖ Java has no default set, while Python and .NET intentionally differ for welcome-page handling.
  • ➖ Adds substantial machinery for only five shared constants.

Recommendation: Keep the PR's binding-local declarations. The small, stable preference set does not justify cross-language generation and packaging infrastructure, while focused tests can pin intended parity and binding-specific behavior.

Files changed (13) +96 / -160

Refactor (5) +25 / -122
FirefoxProfile.csDeclare supported Firefox defaults in .NET +10/-9

Declare supported Firefox defaults in .NET

• Replaces shared JSON deserialization with five binding-local default preferences. Existing profile preferences continue to be appended and remain overridable.

dotnet/src/webdriver/Firefox/FirefoxProfile.cs

Preferences.csRemove frozen preference handling +2/-52

Remove frozen preference handling

• Eliminates JSON-based initialization, immutable preference tracking, and override checks. All stored preferences can now be replaced through setters or appended profile values.

dotnet/src/webdriver/Firefox/Preferences.cs

FirefoxProfile.javaParse existing profiles without defaults stubs +1/-3

Parse existing profiles without defaults stubs

• Constructs 'Preferences' directly from an existing 'user.js' file instead of supplying an empty frozen/mutable JSON document.

java/src/org/openqa/selenium/firefox/FirefoxProfile.java

Preferences.javaRemove unused Java defaults JSON parsing +3/-46

Remove unused Java defaults JSON parsing

• Deletes constructors and parsing logic for frozen and mutable default maps. Reader-based construction now exclusively parses Firefox 'user.js' content.

java/src/org/openqa/selenium/firefox/Preferences.java

firefox_profile.pyDeclare supported Firefox defaults in Python +9/-12

Declare supported Firefox defaults in Python

• Defines six default preferences directly on 'FirefoxProfile' and copies them for newly created profiles. This removes runtime JSON loading while preserving existing-profile and caller-override behavior.

py/selenium/webdriver/firefox/firefox_profile.py

Tests (3) +71 / -27
FirefoxProfileTest.javaUse direct user preference parsing in profile tests +1/-2

Use direct user preference parsing in profile tests

• Updates the helper that reads generated 'user.js' files to use the simplified 'Preferences' constructor.

java/test/org/openqa/selenium/firefox/FirefoxProfileTest.java

PreferencesTest.javaAdapt Java preference tests to simplified constructors +5/-25

Adapt Java preference tests to simplified constructors

• Removes empty-default fixtures and the obsolete frozen-preference test. Parsing tests now pass user preference readers directly.

java/test/org/openqa/selenium/firefox/PreferencesTest.java

firefox_profile_tests.pyCover Python Firefox default preference behavior +65/-0

Cover Python Firefox default preference behavior

• Adds tests for exact generated defaults, untouched existing profile directories, preservation of existing preferences, and caller overrides including the welcome URL.

py/test/unit/selenium/webdriver/firefox/firefox_profile_tests.py

Other (5) +0 / -11
.gitignoreStop ignoring generated Firefox preference JSON +0/-1

Stop ignoring generated Firefox preference JSON

• Removes the obsolete Python-generated 'webdriver_prefs.json' path now that the resource is no longer produced.

.gitignore

BUILD.bazelRemove the .NET shared preference resource +0/-1

Remove the .NET shared preference resource

• Drops 'webdriver_json' from generated .NET resources because Firefox defaults are now declared in C#.

dotnet/src/webdriver/BUILD.bazel

BUILD.bazelRemove obsolete test resource dependency +0/-1

Remove obsolete test resource dependency

• Removes the shared Firefox preference JSON from the .NET test filegroup.

dotnet/test/webdriver/BUILD.bazel

BUILD.bazelRemove Python Firefox defaults resource generation +0/-7

Remove Python Firefox defaults resource generation

• Deletes the copy target for 'webdriver_prefs.json' and removes it from the Firefox Python library's runtime data.

py/BUILD.bazel

python.rakeStop linking the removed Python preference resource +0/-1

Stop linking the removed Python preference resource

• Removes 'firefox/webdriver_prefs.json' from Python local-development generated file links.

rake_tasks/python.rake

@qodo-code-review

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (1) 📜 Skill insights (0)

Grey Divider


Action required

1. New Firefox defaults lack C# tests 📘 Rule violation ☼ Reliability
Description
CreateDefaultPreferences replaces the resource-backed preference set with five inline values, but
this PR adds no active C# unit test that verifies those defaults or their override behavior. The
only FirefoxProfileTests fixture is ignored at class level, so changes to the generated user.js
for new and existing profiles can regress without a binding test detecting them.
Code

dotnet/src/webdriver/Firefox/FirefoxProfile.cs[R269-272]

+        preferences.SetPreference("browser.newtabpage.enabled", false);
+        preferences.SetPreference("browser.startup.homepage", "about:blank");
+        preferences.SetPreference("browser.usedOnWindows10.introURL", "about:blank");
+        preferences.SetPreference("network.captive-portal-service.enabled", false);
Evidence
Compliance rule 5 requires focused unit coverage for applicable behavior changes. The changed C#
implementation introduces five inline defaults, while the repository's corresponding profile test
fixture is disabled with a class-level Ignore attribute and the PR adds no replacement C# test.

AGENTS.md: Prefer Small Unit Tests and Avoid Contract-Misrepresenting Mocks
dotnet/src/webdriver/Firefox/FirefoxProfile.cs[266-275]
dotnet/test/webdriver/Firefox/FirefoxProfileTests.cs[23-24]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new inline Firefox defaults and their override behavior have no active C# unit coverage because the existing Firefox profile test fixture is ignored.

## Fix Focus Areas
- dotnet/src/webdriver/Firefox/FirefoxProfile.cs[266-275]
- dotnet/test/webdriver/Firefox/FirefoxProfileTests.cs[23-108]

## Recommended Fix
Add an active focused unit test that creates a Firefox profile, writes it to disk, and verifies all five default preferences in `user.js`. Also verify that an explicit user preference overrides an inline default; place the tests in a runnable fixture rather than relying on the ignored class.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
Review mode: ⚖️ Balanced: This is a cross-binding behavioral change affecting Firefox profile preference generation and parsing across Python, .NET, and Java, with enough independent logic and compatibility implications to warrant a complete review.

Grey Divider

Tip of the day
💡 Did you know, you can keep summaries lean with Finding overflow, which tucks the rest behind 'View more'

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread dotnet/src/webdriver/Firefox/FirefoxProfile.cs
@titusfortner
titusfortner merged commit 1d7affd into SeleniumHQ:trunk Sep 23, 2026
46 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

B-build Includes scripting, bazel and CI integrations C-dotnet .NET Bindings C-java Java Bindings C-py Python Bindings

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants