Skip to content

HtmlScreenshot: honour OFFICECLI_BROWSER as an explicit chrome-family executable - #318

Open
hesong12 wants to merge 1 commit into
iOfficeAI:mainfrom
hesong12:feat/officecli-browser-env
Open

HtmlScreenshot: honour OFFICECLI_BROWSER as an explicit chrome-family executable#318
hesong12 wants to merge 1 commit into
iOfficeAI:mainfrom
hesong12:feat/officecli-browser-env

Conversation

@hesong12

Copy link
Copy Markdown

Files: src/officecli/Core/HtmlScreenshot.cs (FindChrome()), README.md

Summary

FindChrome() only ever looks for a chrome-family binary by PATH name
(google-chrome, chrome, msedge, …) or a fixed set of platform-standard
install paths (/Applications/Google Chrome.app, …). A host that ships its
own Chromium build outside those locations — for example a pinned
"Chrome for Testing" binary staged under an application-support directory —
has no way to point OfficeCLI at it, and screenshot/mermaid rendering fails
with no_screenshot_backend even though a perfectly good browser is sitting
right there.

This PR adds one explicit override, checked first: OFFICECLI_BROWSER. When
set to a path that exists, FindChrome() returns it immediately, before the
PATH and absolute-path fallbacks. When unset (or pointing at a nonexistent
file), behaviour is byte-for-byte unchanged.

private static string? FindChrome()
{
    // Explicit override first: lets hosts that ship their own Chromium
    // (e.g. a Chrome for Testing build outside the standard install
    // paths) point OfficeCLI at it without touching PATH.
    var explicitBrowser = Environment.GetEnvironmentVariable("OFFICECLI_BROWSER");
    if (!string.IsNullOrWhiteSpace(explicitBrowser) && File.Exists(explicitBrowser))
        return explicitBrowser;

    string[] names = [...]; // unchanged from here down
    ...
}

One README line documents it next to the existing description of the
headless-screenshot rendering path.

Why

Product-side rationale for the host that needed this: a desktop app ships
its own pinned Chrome for Testing binary for its browser-automation feature
and wants OfficeCLI's screenshot/mermaid rendering to reuse that exact
binary instead of requiring a second, separately-installed system Chrome.
OFFICECLI_BROWSER is the minimal, additive way to do that — no new
dependency, no behavior change for anyone who doesn't set it.

Validation

Toolchain: .NET 10 SDK installed to a scratch directory (dotnet-install.sh --channel 10.0), never touching the system SDK. dotnet build src/officecli -c Debug succeeds on the pristine clone and on this branch.

Command sequence, run on macOS with a real Chrome for Testing binary at a
non-standard path and the platform-standard Chrome/Chromium/Edge locations
made unreadable for the duration of the test (sandbox-exec denying
file-read* on /Applications/Google Chrome.app, Chromium.app,
Microsoft Edge.app — i.e. "no browser at a standard location", the exact
condition OFFICECLI_BROWSER exists to solve):

officecli create t.docx
officecli add t.docx /body --type paragraph --prop text=hello
officecli close t.docx

# BEFORE (unmodified main, OFFICECLI_BROWSER not yet read by FindChrome()):
OFFICECLI_BROWSER="$CFT_PATH" officecli view t.docx screenshot -o t.png --json
# → {"success":false,"warnings":[{"message":"No headless browser available. ...
#     Last error: playwright: ...", "code":"warning"}]}   (no_screenshot_backend)
# → t.png: No such file or directory

# AFTER (this branch):
OFFICECLI_BROWSER="$CFT_PATH" officecli view t.docx screenshot -o t.png --json
# → {"success":true,"data":".../t.png","message":".../t.png"}

$CFT_PATH = .../chrome-149.0.7827.22/chrome-mac-arm64/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing.

Result PNG: 1600×1200, 8-bit RGB, 9296 bytes — see attached U1-screenshot.png.

Confirmed the override truly changed behavior (not just "a browser happened
to be found"): the identical command against the unmodified main
branch, with the exact same env var set and the exact same browsers hidden,
still fails with no_screenshot_backend — proving FindChrome() does not
read OFFICECLI_BROWSER before this change, and does after.

Compatibility

Additive only. FindChrome()'s existing PATH-name and absolute-path search
is untouched and still runs whenever OFFICECLI_BROWSER is unset.

Hosts that ship their own Chromium build outside the standard PATH
names / platform install locations (for example a Chrome for Testing
binary staged under an app-support directory) have no way to point
FindChrome() at it. Read OFFICECLI_BROWSER first, before the PATH and
absolute-path fallbacks, when it names an existing file.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bfb9829152

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +417 to +419
var explicitBrowser = Environment.GetEnvironmentVariable("OFFICECLI_BROWSER");
if (!string.IsNullOrWhiteSpace(explicitBrowser) && File.Exists(explicitBrowser))
return explicitBrowser;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Prefer the explicit browser before Playwright

For view ... screenshot on a host with a working playwright CLI, this override is never honored: Capture() iterates Backends(), which tries Playwright before TryChrome, and returns immediately when Playwright succeeds. Consequently, operators cannot force the pinned Chrome-for-Testing executable described in the README whenever Playwright is installed; a valid OFFICECLI_BROWSER should make the Chrome backend run before automatic backend discovery while preserving the existing order when the variable is unset.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant