Skip to content

[dotnet][java][js][rb] deprecate invalid Firefox profile code - #17871

Merged
titusfortner merged 3 commits into
SeleniumHQ:trunkfrom
titusfortner:deprecate-firefox-profile
Aug 5, 2026
Merged

[dotnet][java][js][rb] deprecate invalid Firefox profile code#17871
titusfortner merged 3 commits into
SeleniumHQ:trunkfrom
titusfortner:deprecate-firefox-profile

Conversation

@titusfortner

Copy link
Copy Markdown
Member

🔗 Related Issues

💥 What does this PR do?

  • Deprecates the parts of the Firefox Profile that no longer function, across remaining bindings (Python covered by previous PR), each pointing to its supported replacement.
  • Adds Ruby tests covering the profile behavior that still works, verified locally and against a standalone Grid.

🔧 Implementation Notes

Members marked deprecated:

  • Adding extensions to a profile — all bindings; plus the supporting extension classes (Java and .NET)
  • Accepting untrusted certificates — Java only
  • The legacy WebDriver port preference — Ruby only
  • The no-focus library — Java and Ruby
  • The secure SSL setting — Ruby only

Note that it is technically still possible to add a signed extension to a firefox profile, but not by the methods provided, and this PR opted to mark deprecated rather than re-implement it since we're moving away from this approach with BiDi

🤖 AI assistance

  • AI assisted (complete below)
    • Tool(s): Claude Code
    • What was generated: the cross-binding deprecation markers and the Ruby specs
    • I reviewed all AI output and can explain the change

💡 Additional Considerations

🔄 Types of changes

  • Cleanup (formatting, renaming)

@selenium-ci selenium-ci added C-rb Ruby Bindings C-dotnet .NET Bindings C-java Java Bindings C-nodejs JavaScript Bindings labels Aug 4, 2026
@qodo-code-review

Copy link
Copy Markdown
Contributor

PR Summary by Qodo

Deprecate dead Firefox Profile APIs across bindings; add Ruby profile reuse specs

✨ Enhancement 🧪 Tests 📝 Documentation 🕐 20-40 Minutes

Grey Divider

AI Description

• Deprecates non-functional Firefox Profile members across .NET, Java, JS, and Ruby.
• Points users to supported replacements (driver add-on install, options insecure certs, Service
 config).
• Adds Ruby integration specs validating profile reuse, large profiles, and certificate exception
 persistence.
Diagram

graph TD
  A["Client code"] --> B["Firefox Profile (deprecated)"] --> C["Profile dir (cloned)"] --> D["Geckodriver/Firefox"]
  A --> E["Driver install add-on"] --> D
  A --> F["FirefoxOptions acceptInsecureCerts"] --> D
  G["Ruby integration specs"] --> B
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Hard-delete dead Profile APIs now
  • ➕ Reduces API surface immediately
  • ➕ Avoids carrying deprecated code paths
  • ➖ Breaking change for downstream users
  • ➖ Forces large migrations without deprecation window
2. Re-implement Profile extension install to work again
  • ➕ Preserves legacy workflow for extension pre-installation
  • ➕ May reduce short-term migration pain
  • ➖ Requires ongoing maintenance against Firefox/Geckodriver changes
  • ➖ Conflicts with direction toward runtime install/BiDi-era patterns
3. Keep Profile APIs but internally delegate to runtime driver install
  • ➕ Minimal caller changes while using supported mechanism
  • ➕ Could offer smoother migration path
  • ➖ Not always possible (requires live session/driver instance)
  • ➖ Blurs lifecycle semantics: profile construction vs session-time mutation

Recommendation: Proceed with the current approach: member-level deprecation with clear replacement guidance. It preserves source compatibility while signaling that legacy Profile extension/cert/native-events knobs should be migrated to supported driver/options APIs. Full deletion or re-implementation would either be overly breaking or introduce maintenance burden; delegation to runtime install is not a clean fit for the Profile lifecycle.

Files changed (11) +165 / -27

Enhancement (8) +56 / -5
FirefoxExtension.csMark FirefoxExtension as obsolete in favor of driver add-on install API +1/-0

Mark FirefoxExtension as obsolete in favor of driver add-on install API

• Marks the FirefoxExtension type as obsolete, directing users to FirefoxDriver.InstallAddOnFromFile instead of profile-based installation helpers.

dotnet/src/webdriver/Firefox/FirefoxExtension.cs

FirefoxProfile.csDeprecate profile AddExtension and suppress internal obsolete warnings +7/-0

Deprecate profile AddExtension and suppress internal obsolete warnings

• Marks FirefoxProfile.AddExtension as obsolete with guidance to use FirefoxDriver.InstallAddOnFromFile. Adds targeted CS0618 pragma blocks where FirefoxProfile still references FirefoxExtension internally.

dotnet/src/webdriver/Firefox/FirefoxProfile.cs

ClasspathExtension.javaDeprecate ClasspathExtension in favor of HasExtensions#installExtension +4/-0

Deprecate ClasspathExtension in favor of HasExtensions#installExtension

• Adds Javadoc deprecation guidance and annotates ClasspathExtension as @Deprecated(forRemoval = true), pointing users to HasExtensions#installExtension.

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

Extension.javaDeprecate Extension interface in favor of HasExtensions#installExtension +4/-0

Deprecate Extension interface in favor of HasExtensions#installExtension

• Annotates the Extension interface as @Deprecated(forRemoval = true) and documents the supported replacement API for extension installation.

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

FileExtension.javaDeprecate FileExtension in favor of HasExtensions#installExtension +4/-0

Deprecate FileExtension in favor of HasExtensions#installExtension

• Adds deprecation Javadoc and @Deprecated(forRemoval = true) to steer callers away from profile-based extension packaging.

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

FirefoxProfile.javaDeprecate extension/native-events/cert Profile APIs and suppress internal warnings +22/-0

Deprecate extension/native-events/cert Profile APIs and suppress internal warnings

• Deprecates FirefoxProfile extension-add methods in favor of HasExtensions#installExtension, and deprecates no-focus-lib toggles due to removal of native events. Deprecates untrusted certificate setters in favor of FirefoxOptions#setAcceptInsecureCerts, while adding @SuppressWarnings where deprecated extension types are still used internally.

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

firefox.jsDeprecate Options#addExtensions in favor of Driver#installAddon +1/-0

Deprecate Options#addExtensions in favor of Driver#installAddon

• Adds a JSDoc @deprecated marker to Options#addExtensions directing users to Driver#installAddon for supported extension installation.

javascript/selenium-webdriver/firefox.js

profile.rbAdd runtime deprecation warnings for legacy Firefox::Profile setters and extension install +13/-5

Add runtime deprecation warnings for legacy Firefox::Profile setters and extension install

• Introduces logger-based deprecation notices for Profile#port=, #secure_ssl=, #load_no_focus_lib=, and #add_extension. Removes the attr_writer declarations so these setters can emit deprecation warnings consistently.

rb/lib/selenium/webdriver/firefox/profile.rb

Tests (2) +101 / -22
profile_spec.rbAdd integration coverage for profile reuse, large profiles, and cert exception persistence +101/-0

Add integration coverage for profile reuse, large profiles, and cert exception persistence

• Adds end-to-end tests ensuring preferences from a profile directory are preserved, large base64-encoded profiles are accepted, and stored certificate exceptions (cert_override.txt) are honored when accept_insecure_certs is false. Implements a local self-signed HTTPS WEBrick server to validate the certificate override behavior.

rb/spec/integration/selenium/webdriver/firefox/profile_spec.rb

profile_spec.rbRemove unit tests asserting extension installation via Profile#add_extension +0/-22

Remove unit tests asserting extension installation via Profile#add_extension

• Deletes unit coverage that expects extensions to be installed into the profile directory, aligning tests with the newly-deprecated extension installation pathway.

rb/spec/unit/selenium/webdriver/firefox/profile_spec.rb

Documentation (1) +8 / -0
AGENTS.mdDocument warning suppression pattern for obsolete .NET APIs +8/-0

Document warning suppression pattern for obsolete .NET APIs

• Adds guidance for suppressing CS0618 in narrowly-scoped internal call sites when an obsolete public API is still used internally. Provides a concrete pragma example for keeping builds warning-clean.

dotnet/AGENTS.md

@qodo-code-review

qodo-code-review Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Bad cert serial encoding ✗ Dismissed 🐞 Bug ≡ Correctness
Description
The new Ruby integration spec writes cert_override.txt using certificate.serial.to_s(2), which
produces a textual base-2 string (e.g., "1") rather than the binary serial bytes expected by the
documented db_key format, so Firefox may ignore the stored exception and the TLS navigation can fail
with accept_insecure_certs: false. This makes the new "reuses a stored certificate exception" test
unreliable/incorrect.
Code

rb/spec/integration/selenium/webdriver/firefox/profile_spec.rb[R95-98]

+          serial = certificate.serial.to_s(2)
+          issuer = certificate.issuer.to_der
+          db_key = Base64.strict_encode64([0, 0, serial.bytesize, issuer.bytesize].pack('N4') + serial + issuer)
+          fingerprint = OpenSSL::Digest::SHA256.hexdigest(certificate.to_der).upcase.scan(/../).join(':')
Evidence
The spec’s own comment says the db_key contains <serial> bytes, but the implementation uses
certificate.serial.to_s(2) (a Ruby string representation) and appends it directly into the encoded
db_key. The certificate’s serial is set as an Integer (certificate.serial = 1), making the
string/bytes mismatch concrete.

rb/spec/integration/selenium/webdriver/firefox/profile_spec.rb[92-102]
rb/spec/integration/selenium/webdriver/firefox/profile_spec.rb[124-131]

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

### Issue description
`write_cert_override` encodes the certificate serial as a text string via `certificate.serial.to_s(2)` and uses that in the db_key payload. The method comment states the db_key is base64 of a byte sequence containing `<serial>` bytes, so using ASCII digits risks generating a key Firefox won’t match, causing the cert exception not to be reused.

### Issue Context
This is used by the integration test that sets `accept_insecure_certs: false` and expects navigation to a self-signed HTTPS endpoint to succeed due to the stored override.

### Fix Focus Areas
- rb/spec/integration/selenium/webdriver/firefox/profile_spec.rb[92-102]

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



Remediation recommended

2. HTTPS server start race ✗ Dismissed 🐞 Bug ☼ Reliability
Description
start_https_server starts WEBrick on a background thread and immediately returns without waiting
for the socket to be listening or surfacing thread startup exceptions, so the browser navigation can
race and intermittently hit connection-refused or silently fail server startup. This introduces
flakiness in the new TLS profile reuse integration test.
Code

rb/spec/integration/selenium/webdriver/firefox/profile_spec.rb[R120-121]

+          Thread.new { server.start }
+          {server: server, port: port, certificate: certificate}
Evidence
The new helper returns right after spawning the server thread. In contrast, the existing RackServer
test utility waits for reachability using SocketPoller.connected?, which is the established
pattern in this repo for avoiding startup races.

rb/spec/integration/selenium/webdriver/firefox/profile_spec.rb[104-122]
rb/spec/integration/selenium/webdriver/spec_support/rack_server.rb[36-46]
rb/spec/integration/selenium/webdriver/spec_support/rack_server.rb[93-97]
rb/lib/selenium/webdriver/common/socket_poller.rb[40-43]

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

### Issue description
`start_https_server` launches the HTTPS WEBrick server in a new thread and returns immediately. There is no readiness check before the test uses the URL, and exceptions in the server thread may not reliably fail the example.

### Issue Context
The existing integration test infrastructure already uses `SocketPoller.connected?` to ensure servers are reachable before tests proceed.

### Fix Focus Areas
- rb/spec/integration/selenium/webdriver/firefox/profile_spec.rb[104-122]
- rb/spec/integration/selenium/webdriver/firefox/profile_spec.rb[143-148]

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


To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

Comment thread rb/spec/integration/selenium/webdriver/firefox/profile_spec.rb Outdated
Comment thread rb/spec/integration/selenium/webdriver/firefox/profile_spec.rb Outdated
@titusfortner titusfortner changed the title [dotnet][java][js][rb] deprecate dead Firefox profile members and add reuse specs [dotnet][java][js][rb] deprecate invalid Firefox profile code Aug 4, 2026
@qodo-code-review

qodo-code-review Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

No code changes since the last review — review skipped

Qodo Logo

@titusfortner
titusfortner merged commit 960abd2 into SeleniumHQ:trunk Aug 5, 2026
44 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C-dotnet .NET Bindings C-java Java Bindings C-nodejs JavaScript Bindings C-rb Ruby Bindings

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants