Conversation
PR Summary by QodoExpose protocol-neutral web extension management on Java drivers
AI Description
Diagram
High-Level Assessment
Files changed (25)
|
Code Review by Qodo
1. Extension routing can regress unseen
|
| if (driver.maybeGetBiDi().isPresent()) { | ||
| LOG.fine("Installing web extension over BiDi"); | ||
| return installOverBiDi(source, firefoxOptions); |
There was a problem hiding this comment.
1. Extension routing can regress unseen 📘 Rule violation ☼ Reliability
The new install branch sends every negotiated bidirectional session through installOverBiDi, but no focused test constructs such a session. Firefox vendor serialization, Chromium directory path or upload selection, result validation, and uninstall dispatch can therefore change without the small-test suite detecting it.
Agent Prompt
## Issue description
The new driver-level web-extension implementation contains untested bidirectional routing, including browser-specific source conversion, vendor options, response validation, and uninstall behavior.
## Fix Focus Areas
- java/src/org/openqa/selenium/remote/RemoteWebExtensions.java[84-176]
- java/src/org/openqa/selenium/remote/RemoteWebExtensions.java[215-224]
- java/test/org/openqa/selenium/remote/RemoteWebExtensionsTest.java[48-145]
## Recommended Fix
Extend the focused remote web-extension tests with a controllable bidirectional-session fixture. Verify Firefox vendor parameters and uninstall commands, Chromium local directory paths and remote uploads, and rejection of malformed install results without relying on browser-level tests.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| Map<String, Object> params = new HashMap<>(); | ||
| params.put("addon", source.toBase64()); | ||
| if (firefoxOptions != null) { | ||
| firefoxOptions.isPermanent().ifPresent(permanent -> params.put("temporary", !permanent)); |
There was a problem hiding this comment.
2. Firefox installs persist unexpectedly 🐞 Bug ≡ Correctness
installOverClassic omits temporary unless callers explicitly set permanent, even though the classic Firefox endpoint treats an omitted value as permanent while the API and BiDi path default to temporary installation. On non-BiDi Firefox, a signed extension installed with default options or only private-browsing permission therefore remains in a reused custom profile after the session, whereas the same call through BiDi is removed automatically.
Agent Prompt
## Issue description
Firefox extension installation has different persistence semantics depending on transport: the classic request omits `temporary` unless `permanent(...)` is explicitly set, and geckodriver interprets that omission as a permanent installation, while the API and BiDi Firefox behavior default to temporary installation. This also affects option sets that only configure private-browsing access.
## Fix Focus Areas
- java/src/org/openqa/selenium/remote/RemoteWebExtensions.java[179-188]
- java/test/org/openqa/selenium/remote/RemoteWebExtensionsTest.java[48-72]
## Recommended Fix
Always add the classic `temporary` parameter, deriving it as the inverse of `firefoxOptions.isPermanent().orElse(false)`. This makes absent options and options that only set private-browsing access send `temporary: true`, while `permanent(true)` sends `temporary: false`; update the tests to verify both default temporary installation and explicit permanent installation.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| Path directory = requireNonNullPath(source); | ||
| String resolved = | ||
| browserSharesFilesystem() | ||
| ? directory.toAbsolutePath().toString() | ||
| : uploadDirectory(directory); |
There was a problem hiding this comment.
3. Kubernetes grid cannot install folders 🐞 Bug ≡ Correctness
extensionData routes remote Chromium directories through uploadDirectory, which assumes the file-upload command returns a response containing the extracted remote path. Grid dispatches that request to OneShotNode.uploadFile, which returns null, so Chromium directory installation on a Kubernetes one-shot node fails before the BiDi install command is sent.
Agent Prompt
## Issue description
Remote Chromium directory installation depends on the Grid file-upload endpoint, but Kubernetes one-shot nodes return no upload response and the client cannot obtain a browser-visible directory path.
## Fix Focus Areas
- java/src/org/openqa/selenium/remote/RemoteWebExtensions.java[169-176]
- java/src/org/openqa/selenium/remote/RemoteWebExtensions.java[215-224]
- java/src/org/openqa/selenium/grid/node/k8s/OneShotNode.java[339-343]
## Recommended Fix
Implement `OneShotNode.uploadFile` with the same single-root extraction and path response semantics used by `LocalNode`, or forward the upload to the environment that owns the browser. Add an integration test covering a Chromium directory installation through this node type.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) { | ||
| try (ZipOutputStream zos = new ZipOutputStream(bos)) { | ||
| addToZip(parent.getAbsolutePath(), zos, absolute); | ||
| } |
There was a problem hiding this comment.
4. Unreadable folders become partial uploads 🐞 Bug ☼ Reliability
zipToBase64PreservingRoot delegates traversal to addToZip, which catches directory-enumeration failures, logs them, and continues instead of propagating the declared IOException. When any extension subtree is unreadable, Grid receives a successful but incomplete archive and the eventual install fails remotely with missing manifest or resource data rather than identifying the local read failure.
Agent Prompt
## Issue description
The new root-preserving zip operation can silently produce incomplete extension uploads because its shared traversal helper suppresses directory read failures.
## Fix Focus Areas
- java/src/org/openqa/selenium/io/Zip.java[68-78]
- java/src/org/openqa/selenium/io/Zip.java[82-93]
- java/test/org/openqa/selenium/io/ZipTest.java[95-107]
## Recommended Fix
Remove the catch that suppresses `IOException` from directory enumeration and let traversal failures propagate through `zipToBase64PreservingRoot`. Add a test demonstrating that an unreadable subtree fails the operation instead of producing a partial archive.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
🔗 Related Issues
Related to #17933
💥 What does this PR do?
Ensures that extension can be installed directly on the driver instance and fall backs on classic for Firefox as required.
🔧 Implementation Notes
🤖 AI assistance
💡 Additional Considerations
🔄 Types of changes