Skip to content

Commit 3612e79

Browse files
authored
Merge pull request #709 from marp-team/docker-set-xdg-directories
Fix failure to launch Chromium if the user specified by MARP_USER env does not exist in the Docker container image
2 parents bd06d70 + 9369b4c commit 3612e79

File tree

6 files changed

+25
-40
lines changed

6 files changed

+25
-40
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
- Fix ambiguous CLI arguments parsing for `--output` ([#684](https://github.com/marp-team/marp-cli/issues/684), [#685](https://github.com/marp-team/marp-cli/pull/685))
2323
- Make more sensible error detection while connecting to browser ([#706](https://github.com/marp-team/marp-cli/pull/706))
24+
- Fix failure to launch Chromium if the user specified by `MARP_USER` env does not exist in the Docker container image ([#702](https://github.com/marp-team/marp-cli/issues/702), [#709](https://github.com/marp-team/marp-cli/pull/709))
2425

2526
## v4.2.3 - 2025-08-09
2627

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ RUN apt update && \
2727
npm cache clean --force
2828

2929
# Set environments
30-
ENV MARP_USER=marp:marp PATH=$PATH:/home/marp/.cli CHROME_PATH=/usr/local/bin/chrome
30+
ENV MARP_USER=marp:marp PATH=$PATH:/home/marp/.cli CHROME_PATH=/usr/local/bin/chrome CHROME_CONFIG_HOME=/tmp/marp-config
3131

3232
# Copy Marp CLI files
3333
USER marp

package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/browser/browsers/chrome.ts

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,17 @@ export class ChromeBrowser extends Browser {
1414
protected async launchPuppeteer(
1515
opts: Omit<LaunchOptions, 'userDataDir'> // userDataDir cannot overload in current implementation
1616
): Promise<PuppeteerBrowser> {
17-
const ignoreDefaultArgsSet = new Set(
18-
typeof opts.ignoreDefaultArgs === 'object' ? opts.ignoreDefaultArgs : []
19-
)
20-
21-
// Escape hatch for force-extensions policy for Chrome enterprise
22-
// https://github.com/puppeteer/puppeteer/blob/master/docs/troubleshooting.md#chrome-headless-doesnt-launch-on-windows
23-
// https://github.com/marp-team/marp-cli/issues/231
24-
if (process.env.CHROME_ENABLE_EXTENSIONS) {
25-
ignoreDefaultArgsSet.add('--disable-extensions')
26-
}
27-
2817
const baseOpts = await this.generateLaunchOptions({
18+
// Escape hatch for force-extensions policy for Chrome enterprise
19+
// https://github.com/puppeteer/puppeteer/blob/master/docs/troubleshooting.md#chrome-headless-doesnt-launch-on-windows
20+
// https://github.com/marp-team/marp-cli/issues/231
21+
enableExtensions: !!process.env.CHROME_ENABLE_EXTENSIONS,
2922
headless: this.puppeteerHeadless(),
3023
pipe: await this.puppeteerPipe(),
3124
// userDataDir: await this.puppeteerDataDir(), // userDataDir will set in args option due to wrong path normalization in WSL
3225
...opts,
3326
userDataDir: undefined,
3427
args: await this.puppeteerArgs(opts.args ?? []),
35-
ignoreDefaultArgs: opts.ignoreDefaultArgs === true || [
36-
...ignoreDefaultArgsSet,
37-
],
3828
})
3929

4030
const tryLaunch = async (

src/error.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ export function error(
3838
throw cliError
3939
}
4040

41+
// TODO: Use Error.isError instead, in Node.js v24.3+
42+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/isError
4143
export const isError = (e: unknown): e is NodeJS.ErrnoException => {
4244
if (e instanceof Error) return true
4345

test/browser/browsers/chrome.ts

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ describe('ChromeBrowser', () => {
7171
args: expect.arrayContaining([
7272
expect.stringMatching(/^--user-data-dir=/),
7373
]),
74-
ignoreDefaultArgs: [],
74+
enableExtensions: false,
7575
})
7676
)
7777
})
@@ -145,41 +145,34 @@ describe('ChromeBrowser', () => {
145145
})
146146

147147
describe('Disabling extensions', () => {
148-
it('ignores --disable-extensions argument if CHROME_ENABLE_EXTENSIONS environment variable is defined', async () => {
148+
it('enables extensions if CHROME_ENABLE_EXTENSIONS environment variable is defined', async () => {
149149
process.env.CHROME_ENABLE_EXTENSIONS = '1'
150150
await new ChromeBrowser({ path: '/path/to/chrome' }).launch()
151151

152152
expect(puppeteer.launch).toHaveBeenCalledWith(
153-
expect.objectContaining({
154-
ignoreDefaultArgs: expect.arrayContaining([
155-
'--disable-extensions',
156-
]),
157-
})
153+
expect.objectContaining({ enableExtensions: true })
158154
)
159155
})
160156

161-
it('does not ignore --disable-extensions argument if CHROME_ENABLE_EXTENSIONS environment variable is empty', async () => {
157+
it('does not enable extensions if CHROME_ENABLE_EXTENSIONS environment variable is empty', async () => {
162158
process.env.CHROME_ENABLE_EXTENSIONS = ''
163159
await new ChromeBrowser({ path: '/path/to/chrome' }).launch()
164160

165161
expect(puppeteer.launch).toHaveBeenCalledWith(
166-
expect.objectContaining({ ignoreDefaultArgs: [] })
162+
expect.objectContaining({ enableExtensions: false })
167163
)
168164
})
169165

170-
it('merges ignoreDefaultArgs if passed extra ignore args', async () => {
166+
it('passes through ignoreDefaultArgs if passed extra ignore args', async () => {
171167
process.env.CHROME_ENABLE_EXTENSIONS = 'true'
172168
await new ChromeBrowser({ path: '/path/to/chrome' }).launch({
173169
ignoreDefaultArgs: ['--foo', '--bar'],
174170
})
175171

176172
expect(puppeteer.launch).toHaveBeenCalledWith(
177173
expect.objectContaining({
178-
ignoreDefaultArgs: expect.arrayContaining([
179-
'--disable-extensions',
180-
'--foo',
181-
'--bar',
182-
]),
174+
enableExtensions: true,
175+
ignoreDefaultArgs: expect.arrayContaining(['--foo', '--bar']),
183176
})
184177
)
185178
})
@@ -191,22 +184,21 @@ describe('ChromeBrowser', () => {
191184
})
192185

193186
expect(puppeteer.launch).toHaveBeenCalledWith(
194-
expect.objectContaining({ ignoreDefaultArgs: true })
187+
expect.objectContaining({
188+
enableExtensions: true,
189+
ignoreDefaultArgs: true,
190+
})
195191
)
196192
})
197193

198-
it('keeps ignoring --disable-extensions argument even if explicitly passed ignoreDefaultArgs as false', async () => {
194+
it('enables extensions even if explicitly passed ignoreDefaultArgs as false', async () => {
199195
process.env.CHROME_ENABLE_EXTENSIONS = 'enabled'
200196
await new ChromeBrowser({ path: '/path/to/chrome' }).launch({
201197
ignoreDefaultArgs: false,
202198
})
203199

204200
expect(puppeteer.launch).toHaveBeenCalledWith(
205-
expect.objectContaining({
206-
ignoreDefaultArgs: expect.arrayContaining([
207-
'--disable-extensions',
208-
]),
209-
})
201+
expect.objectContaining({ enableExtensions: true })
210202
)
211203
})
212204
})

0 commit comments

Comments
 (0)