From 83b6112c9e257604f2d42cdd3ced7924d2fe4111 Mon Sep 17 00:00:00 2001 From: Yuki Hattori Date: Tue, 31 Dec 2024 23:38:15 +0900 Subject: [PATCH 01/10] Add `markdown.marp.browser` and `markdown.marp.browserPath` settings --- README.md | 10 +++++--- package.json | 27 ++++++++++++++++++++-- src/marp-cli.ts | 8 +------ src/option.ts | 61 ++++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 91 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 69bd4a33..676c4f71 100644 --- a/README.md +++ b/README.md @@ -128,9 +128,13 @@ You can also execute command from the Command Palette (F1 or Ctr - **PNG** (_First slide only)_ - **JPEG** (_First slide only)_ -Default file type can choose by `markdown.marp.exportType` preference. +Default file type can choose by the `markdown.marp.exportType` setting. -> ⚠️ Export except HTML requires to install any one of [Google Chrome](https://www.google.com/chrome/), [Chromium](https://www.chromium.org/), or [Microsoft Edge](https://www.microsoft.com/edge). You may also specify the custom path for Chrome / Chromium-based browser by preference `markdown.marp.chromePath`. +> [!IMPORTANT] +> Exporting PDF, PPTX, and image formats requires to install any one of [Google Chrome](https://www.google.com/chrome/), [Chromium](https://www.chromium.org/), [Microsoft Edge](https://www.microsoft.com/edge), or [Firefox](https://www.mozilla.org/firefox/). You may control using browser and the custom path for the browser by `markdown.marp.browser` and `markdown.marp.browserPath` settings. + +> [!NOTE] +> A legacy setting `markdown.marp.chromePath` is deprecated since v2. Please use `markdown.marp.browserPath` instead. ### Use custom theme CSS 🛡️ @@ -175,7 +179,7 @@ Markdown preview will reload updated theme CSS automatically when you edited the ### Outline extension -When Marp Markdown is enabled, you can use the extended [outline view](https://code.visualstudio.com/docs/languages/markdown#_outline-view) like following. They are enabled by default but you may disable by `markdown.marp.outlineExtension` preference. +When Marp Markdown is enabled, you can use the extended [outline view](https://code.visualstudio.com/docs/languages/markdown#_outline-view) like following. They are enabled by default but you may disable by the `markdown.marp.outlineExtension` setting. #### Outline view for each slide diff --git a/package.json b/package.json index 9368c6b6..5c0ff6f8 100644 --- a/package.json +++ b/package.json @@ -115,10 +115,27 @@ "Use inherited setting from `#markdown.preview.breaks#`." ] }, - "markdown.marp.chromePath": { + "markdown.marp.browser": { + "type": "string", + "enum": [ + "auto", + "chrome", + "edge", + "firefox" + ], + "default": "auto", + "description": "Controls the installed browser using internally to export PDF, PPTX, and the image.", + "enumDescriptions": [ + "Automatically detect Chrome, Chromium, Edge, or Firefox.", + "Use Google Chrome.", + "Use Microsoft Edge.", + "Use Mozilla Firefox." + ] + }, + "markdown.marp.browserPath": { "type": "string", "default": "", - "description": "Sets the custom path for Chrome or Chromium-based browser to export PDF, PPTX, and image. If it's empty, Marp will find out the installed Google Chrome / Chromium / Microsoft Edge." + "markdownDescription": "Configure the custom path for the installed browser using internally to export PDF, PPTX, and the image. The kind of browser is determined by `#markdown.marp.browser#`. When set to empty, Marp will find out a suitable installed browser automatically." }, "markdown.marp.html": { "type": "string", @@ -214,6 +231,12 @@ "default": false, "description": "Enables all HTML elements in Marp Markdown. This setting is working only in the trusted workspace.", "deprecationMessage": "The setting \"markdown.marp.enableHtml\" is deprecated. Please use \"markdown.marp.html\" instead." + }, + "markdown.marp.chromePath": { + "type": "string", + "default": "", + "description": "Sets the custom path for Chrome or Chromium-based browser to export PDF, PPTX, and image. If it's empty, Marp will find out the installed Google Chrome / Chromium / Microsoft Edge.", + "deprecationMessage": "The setting \"markdown.marp.chromePath\" is deprecated. Please use \"markdown.marp.browserPath\" instead." } } }, diff --git a/src/marp-cli.ts b/src/marp-cli.ts index 43cc4ab6..2576d19a 100644 --- a/src/marp-cli.ts +++ b/src/marp-cli.ts @@ -88,21 +88,17 @@ export default async function runMarpCli( const { marpCli, CLIError, CLIErrorCode } = await import( '@marp-team/marp-cli' ) - const { CHROME_PATH } = process.env let exitCode: number try { - process.env.CHROME_PATH = - marpConfiguration().get('chromePath') || CHROME_PATH - exitCode = await marpCli(argv, opts) } catch (e) { console.error(e) if ( e instanceof CLIError && - e.errorCode === CLIErrorCode.NOT_FOUND_CHROMIUM + e.errorCode === CLIErrorCode.NOT_FOUND_BROWSER ) { const browsers = ['[Google Chrome](https://www.google.com/chrome/)'] @@ -119,8 +115,6 @@ export default async function runMarpCli( } throw e - } finally { - process.env.CHROME_PATH = CHROME_PATH } if (exitCode !== 0) { diff --git a/src/option.ts b/src/option.ts index 74e68620..d0e3e498 100644 --- a/src/option.ts +++ b/src/option.ts @@ -1,5 +1,6 @@ import { tmpdir } from 'node:os' import path from 'node:path' +import type { Config } from '@marp-team/marp-cli' import { MarpOptions } from '@marp-team/marp-core' import { Options } from 'markdown-it' import { nanoid } from 'nanoid' @@ -18,6 +19,12 @@ export interface WorkFile { cleanup: () => Promise } +export interface ConfigForCLI extends Config { + vscode: { + themeFiles: WorkFile[] + } +} + let cachedPreviewOption: MarpOptions | undefined const breaks = (inheritedValue: boolean): boolean => { @@ -112,11 +119,60 @@ export const marpCoreOptionForCLI = async ( ) => { const confMdPreview = workspace.getConfiguration('markdown.preview', uri) + let browser = marpConfiguration().get<'auto' | 'chrome' | 'edge' | 'firefox'>( + 'browser', + ) + + const browserPath = (() => { + const browserPath = marpConfiguration().get('browserPath') + if (browserPath) { + // If `markdown.marp.browserPath` is `auto`, detect the kind of browser by the binary name + if (browser === 'auto') { + try { + const binaryName = path.basename(browserPath).toLowerCase() + + if (binaryName.includes('firefox') || binaryName.includes('fx')) + browser = 'firefox' + } catch (e) { + console.error(e) + console.warn( + 'Failed to detect the kind of browser by the binary name.', + ) + } + } + + return browserPath + } + + // Legacy compatibility + const chromePath = marpConfiguration().get('chromePath') + if (chromePath) { + // Show warning for legacy configuration + window + .showWarningMessage( + 'The setting "markdown.marp.chromePath" is deprecated. Please use "markdown.marp.browserPath" instead. Please review your settings JSON to make silence this warning.', + 'Open Extension Settings', + ) + .then((selected) => { + if (selected) void openExtensionSettings() + }) + + // Force to use Chrome if `markdown.marp.chromePath` is set + browser = 'chrome' + + return chromePath + } + + return undefined + })() + const baseOpts = { allowLocalFiles, pdfNotes, pdfOutlines: pdfOutlines(), html: html().value, + browser: browser || 'auto', + browserPath, options: { markdown: { breaks: breaks(!!confMdPreview.get('breaks')), @@ -125,8 +181,7 @@ export const marpCoreOptionForCLI = async ( math: math(), }, themeSet: [] as string[], - vscode: {} as Record, - } + } as ConfigForCLI const workspaceFolder = workspace.getWorkspaceFolder(uri) const parentFolder = uri.scheme === 'file' && path.dirname(uri.fsPath) @@ -166,7 +221,7 @@ export const marpCoreOptionForCLI = async ( ).filter((w): w is WorkFile => !!w) baseOpts.themeSet = themeFiles.map((w) => w.path) - baseOpts.vscode.themeFiles = themeFiles + baseOpts.vscode = { themeFiles } return baseOpts } From 8abe856b8eae63591e170a9d772a36a0f5e3980f Mon Sep 17 00:00:00 2001 From: Yuki Hattori Date: Wed, 1 Jan 2025 02:30:19 +0900 Subject: [PATCH 02/10] Update tests about new browser options --- src/__mocks__/vscode.ts | 8 +++-- src/commands/export.test.ts | 61 ++++++++++++++++++++++++++++++++++ src/commands/export.ts | 55 +++++++++++++++++++++++++++++-- src/marp-cli.test.ts | 65 ------------------------------------- src/marp-cli.ts | 42 ++++++++++++------------ src/option.test.ts | 58 ++++++++++++++++++++++++++++++++- 6 files changed, 196 insertions(+), 93 deletions(-) diff --git a/src/__mocks__/vscode.ts b/src/__mocks__/vscode.ts index 3fe2ca4b..bf96eb32 100644 --- a/src/__mocks__/vscode.ts +++ b/src/__mocks__/vscode.ts @@ -5,14 +5,18 @@ type MockedConf = Record const defaultVSCodeVersion = 'v1.62.1' const defaultConf: MockedConf = { 'markdown.marp.breaks': 'on', - 'markdown.marp.chromePath': '', - 'markdown.marp.enableHtml': false, + 'markdown.marp.browser': 'auto', + 'markdown.marp.browserPath': '', 'markdown.marp.html': 'default', 'markdown.marp.exportType': 'pdf', 'markdown.marp.outlineExtension': true, 'markdown.marp.pdf.noteAnnotations': false, 'markdown.marp.pdf.outlines': 'off', 'window.zoomLevel': 0, + + // Legacy + 'markdown.marp.chromePath': '', + 'markdown.marp.enableHtml': false, } let currentConf: MockedConf = {} diff --git a/src/commands/export.test.ts b/src/commands/export.test.ts index 8556ea0a..ea45bec6 100644 --- a/src/commands/export.test.ts +++ b/src/commands/export.test.ts @@ -1,3 +1,4 @@ +import * as marpCliModule from '@marp-team/marp-cli' import { commands, env, window, workspace } from 'vscode' import * as marpCli from '../marp-cli' import * as option from '../option' @@ -317,6 +318,66 @@ describe('#doExport', () => { }) }) + describe('when CLI was thrown CLIError with BROWSER_NOT_FOUND error code', () => { + it.each` + browser | platform | expected + ${'auto'} | ${'win32'} | ${['Google Chrome', 'Microsoft Edge', 'Firefox']} + ${'auto'} | ${'darwin'} | ${['Google Chrome', 'Microsoft Edge', 'Firefox']} + ${'auto'} | ${'linux'} | ${['Google Chrome', 'Chromium', 'Microsoft Edge', 'Firefox']} + ${'chrome'} | ${'win32'} | ${['Google Chrome']} + ${'chrome'} | ${'darwin'} | ${['Google Chrome']} + ${'chrome'} | ${'linux'} | ${['Google Chrome', 'Chromium']} + ${'edge'} | ${'win32'} | ${['Microsoft Edge']} + ${'edge'} | ${'darwin'} | ${['Microsoft Edge']} + ${'edge'} | ${'linux'} | ${['Microsoft Edge']} + ${'firefox'} | ${'win32'} | ${['Firefox']} + ${'firefox'} | ${'darwin'} | ${['Firefox']} + ${'firefox'} | ${'linux'} | ${['Firefox']} + `( + 'throws MarpCLIError with the message contains $expected to suggest browsers when running on $platform with browser option as $browser', + async ({ browser, platform, expected }) => { + expect.assertions(expected.length + 1) + setConfiguration({ 'markdown.marp.browser': browser }) + + const { platform: originalPlatform } = process + + try { + Object.defineProperty(process, 'platform', { value: platform }) + + const consoleDebug = jest.spyOn(console, 'debug').mockImplementation() + const consoleInfo = jest.spyOn(console, 'info').mockImplementation() + const marpCliMock = jest + .spyOn(marpCliModule, 'marpCli') + .mockRejectedValue( + new marpCliModule.CLIError( + 'mocked error', + marpCliModule.CLIErrorCode.NOT_FOUND_BROWSER, + ), + ) + + try { + await exportModule.doExport(saveURI(), document) + expect(window.showErrorMessage).toHaveBeenCalledTimes(1) + + for (const fragment of expected) { + expect(window.showErrorMessage).toHaveBeenCalledWith( + expect.stringContaining(fragment), + ) + } + } finally { + consoleDebug.mockRestore() + consoleInfo.mockRestore() + marpCliMock.mockRestore() + } + } finally { + Object.defineProperty(process, 'platform', { + value: originalPlatform, + }) + } + }, + ) + }) + describe('when the save path has non-file scheme', () => { it('exports the document into temporally path and copy it to the save path', async () => { const marpCliMock = jest.spyOn(marpCli, 'default').mockImplementation() diff --git a/src/commands/export.ts b/src/commands/export.ts index 71c6ab41..86bedb7b 100644 --- a/src/commands/export.ts +++ b/src/commands/export.ts @@ -45,6 +45,13 @@ const descriptions = { [Types.jpeg]: 'JPEG image (first slide only)' as const, } +const browsers = { + chrome: '[Google Chrome](https://www.google.com/chrome/)', + chromium: '[Chromium](https://www.chromium.org/)', + edge: '[Microsoft Edge](https://www.microsoft.com/edge)', + firefox: '[Mozilla Firefox](https://www.mozilla.org/firefox/)', +} as const + export const ITEM_CONTINUE_TO_EXPORT = 'Continue to export...' export const ITEM_MANAGE_WORKSPACE_TRUST = 'Manage Workspace Trust...' @@ -140,9 +147,51 @@ export const doExport = async (uri: Uri, document: TextDocument) => { }) try { - await marpCli(['-c', conf.path, input.path, '-o', outputPath], { - baseUrl, - }) + await marpCli( + ['-c', conf.path, input.path, '-o', outputPath], + { baseUrl }, + { + onCLIError: ({ error, codes }) => { + if (error.errorCode === codes.NOT_FOUND_BROWSER) { + // Throw error with user-friendly instructions based on the current configuration + const browserOption = marpConfiguration().get('browser') + const suggestBrowsers: string[] = [] + + switch (browserOption) { + case 'chrome': + suggestBrowsers.push( + ...[ + browsers.chrome, + process.platform === 'linux' ? browsers.chromium : '', + ].filter((b) => !!b), + ) + break + case 'edge': + suggestBrowsers.push(browsers.edge) + break + case 'firefox': + suggestBrowsers.push(browsers.firefox) + break + default: + suggestBrowsers.push( + ...[ + browsers.chrome, + process.platform === 'linux' ? browsers.chromium : '', + browsers.edge, + browsers.firefox, + ].filter((b) => !!b), + ) + } + + throw new MarpCLIError( + `It requires to install a suitable browser, ${suggestBrowsers + .join(', ') + .replace(/, ([^,]*)$/, ' or $1')} for exporting.`, + ) + } + }, + }, + ) if (outputToLocalFS) { env.openExternal(uri) diff --git a/src/marp-cli.test.ts b/src/marp-cli.test.ts index 80e0adc7..6ae48e1a 100644 --- a/src/marp-cli.test.ts +++ b/src/marp-cli.test.ts @@ -7,10 +7,6 @@ import { textEncoder } from './utils' jest.mock('vscode') -const setConfiguration: (conf?: Record) => void = ( - workspace as any -)._setConfiguration - describe('Marp CLI integration', () => { const runMarpCli = marpCli.default @@ -50,67 +46,6 @@ describe('Marp CLI integration', () => { marpCliMock.mockRestore() } }) - - it.each` - platform | expected - ${'win32'} | ${[/Google Chrome/, /Microsoft Edge/]} - ${'darwin'} | ${[/Google Chrome/, /Microsoft Edge/]} - ${'linux'} | ${[/Google Chrome/, /Chromium/]} - `( - 'contains $expected to suggested browsers in error message when running on $platform', - async ({ platform, expected }) => { - expect.assertions(expected.length) - - const originalPlatform = process.platform - - try { - Object.defineProperty(process, 'platform', { value: platform }) - - const marpCliMock = jest - .spyOn(marpCliModule, 'marpCli') - .mockRejectedValue( - new marpCliModule.CLIError( - 'mocked error', - marpCliModule.CLIErrorCode.NOT_FOUND_CHROMIUM, - ), - ) - - try { - for (const fragment of expected) { - await expect(runMarpCli(['--version'])).rejects.toThrow(fragment) - } - } finally { - marpCliMock.mockRestore() - } - } finally { - Object.defineProperty(process, 'platform', { value: originalPlatform }) - } - }, - ) - - describe('with markdown.marp.chromePath preference', () => { - it('runs Marp CLI with overridden CHROME_PATH environment', async () => { - const { CHROME_PATH } = process.env - expect(process.env.CHROME_PATH).toBe(CHROME_PATH) - - setConfiguration({ 'markdown.marp.chromePath': __filename }) - - const marpCliMock = jest - .spyOn(marpCliModule, 'marpCli') - .mockImplementation(async () => { - expect(process.env.CHROME_PATH).toBe(__filename) - return 0 - }) - - try { - await runMarpCli(['--version']) - expect(marpCliMock).toHaveBeenCalled() - expect(process.env.CHROME_PATH).toBe(CHROME_PATH) - } finally { - marpCliMock.mockRestore() - } - }) - }) }) describe('#createWorkFile', () => { diff --git a/src/marp-cli.ts b/src/marp-cli.ts index 2576d19a..a0724c01 100644 --- a/src/marp-cli.ts +++ b/src/marp-cli.ts @@ -1,10 +1,14 @@ import { tmpdir } from 'node:os' import path from 'node:path' -import type { marpCli } from '@marp-team/marp-cli' +import type { + marpCli, + CLIError as CLIErrorType, + CLIErrorCode as CLIErrorCodeType, +} from '@marp-team/marp-cli' import { nanoid } from 'nanoid' import { TextDocument, Uri, workspace } from 'vscode' import { WorkFile, marpCoreOptionForCLI } from './option' -import { marpConfiguration, writeFile, unlink } from './utils' +import { writeFile, unlink } from './utils' const createCleanup = (target: Uri) => async () => { await unlink(target) @@ -12,6 +16,15 @@ const createCleanup = (target: Uri) => async () => { export class MarpCLIError extends Error {} +export interface RunMarpCLIOptions { + onCLIError?: (e: MarpCLIErrorHandler) => void +} + +export interface MarpCLIErrorHandler { + error: CLIErrorType + codes: typeof CLIErrorCodeType +} + export async function createWorkFile(doc: TextDocument): Promise { // Use a real file if posibble if (doc.uri.scheme === 'file' && !doc.isDirty) { @@ -81,7 +94,9 @@ export async function createConfigFile( } export default async function runMarpCli( - ...[argv, opts]: Parameters + argv: Parameters[0], + opts?: Parameters[1], + { onCLIError }: RunMarpCLIOptions = {}, ): Promise { console.info(`Execute Marp CLI [${argv.join(' ')}] (${JSON.stringify(opts)})`) @@ -94,26 +109,9 @@ export default async function runMarpCli( try { exitCode = await marpCli(argv, opts) } catch (e) { - console.error(e) - - if ( - e instanceof CLIError && - e.errorCode === CLIErrorCode.NOT_FOUND_BROWSER - ) { - const browsers = ['[Google Chrome](https://www.google.com/chrome/)'] - - if (process.platform === 'linux') - browsers.push('[Chromium](https://www.chromium.org/)') - - browsers.push('[Microsoft Edge](https://www.microsoft.com/edge)') - - throw new MarpCLIError( - `It requires to install ${browsers - .join(', ') - .replace(/, ([^,]*)$/, ' or $1')} for exporting.`, - ) - } + if (e instanceof CLIError) onCLIError?.({ error: e, codes: CLIErrorCode }) + console.error(e) throw e } diff --git a/src/option.test.ts b/src/option.test.ts index 6bb96cf5..de44c2e8 100644 --- a/src/option.test.ts +++ b/src/option.test.ts @@ -1,5 +1,5 @@ import * as nodeFetch from 'node-fetch' -import { Uri, workspace } from 'vscode' +import { Uri, window, workspace } from 'vscode' import * as option from './option' import { textEncoder } from './utils' @@ -110,6 +110,62 @@ describe('Option', () => { }) }) + it('sets correct browser option and browser path option', async () => { + setConfiguration({ + 'markdown.marp.browser': 'chrome', + 'markdown.marp.browserPath': '', + }) + expect(await subject({ uri: untitledUri })).toStrictEqual( + expect.objectContaining({ + browser: 'chrome', + browserPath: undefined, + }), + ) + + // With browser path + setConfiguration({ + 'markdown.marp.browser': 'auto', + 'markdown.marp.browserPath': '/path/to/browser', + }) + expect(await subject({ uri: untitledUri })).toStrictEqual( + expect.objectContaining({ + browser: 'auto', + browserPath: '/path/to/browser', + }), + ) + + // Firefox browser auto detection + setConfiguration({ + 'markdown.marp.browser': 'auto', + 'markdown.marp.browserPath': '/path/to/firefox', + }) + expect(await subject({ uri: untitledUri })).toStrictEqual( + expect.objectContaining({ + browser: 'firefox', + browserPath: '/path/to/firefox', + }), + ) + + // [Legacy] markdown.marp.chromePath + setConfiguration({ + 'markdown.marp.browser': 'auto', + 'markdown.marp.browserPath': '', + 'markdown.marp.chromePath': '/path/to/browser', + }) + expect(await subject({ uri: untitledUri })).toStrictEqual( + expect.objectContaining({ + browser: 'chrome', + browserPath: '/path/to/browser', + }), + ) + expect(window.showWarningMessage).toHaveBeenCalledWith( + expect.stringContaining( + 'The setting "markdown.marp.chromePath" is deprecated', + ), + expect.anything(), + ) + }) + describe('when targeted document belongs to workspace', () => { const css = '/* @theme test */' From 3f74f526580ecf021882b38a2f108945b5162c8f Mon Sep 17 00:00:00 2001 From: Yuki Hattori Date: Wed, 1 Jan 2025 02:37:18 +0900 Subject: [PATCH 03/10] Refactor a test for exporting --- src/commands/export.test.ts | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/commands/export.test.ts b/src/commands/export.test.ts index ea45bec6..dc933a4b 100644 --- a/src/commands/export.test.ts +++ b/src/commands/export.test.ts @@ -344,16 +344,17 @@ describe('#doExport', () => { try { Object.defineProperty(process, 'platform', { value: platform }) - const consoleDebug = jest.spyOn(console, 'debug').mockImplementation() - const consoleInfo = jest.spyOn(console, 'info').mockImplementation() - const marpCliMock = jest - .spyOn(marpCliModule, 'marpCli') - .mockRejectedValue( - new marpCliModule.CLIError( - 'mocked error', - marpCliModule.CLIErrorCode.NOT_FOUND_BROWSER, - ), - ) + const runMarpCLI = jest + .spyOn(marpCli, 'default') + .mockImplementation(async (_, __, opts) => { + opts?.onCLIError?.({ + error: new marpCliModule.CLIError( + 'mocked error', + marpCliModule.CLIErrorCode.NOT_FOUND_BROWSER, + ), + codes: marpCliModule.CLIErrorCode, + }) + }) try { await exportModule.doExport(saveURI(), document) @@ -365,9 +366,7 @@ describe('#doExport', () => { ) } } finally { - consoleDebug.mockRestore() - consoleInfo.mockRestore() - marpCliMock.mockRestore() + runMarpCLI.mockRestore() } } finally { Object.defineProperty(process, 'platform', { From fc227182d1c58970b54e914cdaee8c53b992fee7 Mon Sep 17 00:00:00 2001 From: Yuki Hattori Date: Wed, 1 Jan 2025 03:07:37 +0900 Subject: [PATCH 04/10] Run test with `-i` option on CI test with Node 18 --- .circleci/config.yml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 582ef42c..edab66a8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -44,6 +44,10 @@ commands: - run: npm run check:audit test: + parameters: + run-in-band: + type: boolean + default: false steps: - checkout - install @@ -66,7 +70,7 @@ commands: - run: name: Jest - command: npm run test:unit:coverage -- --ci --maxWorkers=2 --reporters=default --reporters=jest-junit + command: npm run test:unit:coverage -- --ci --maxWorkers=2 <<# parameters.run-in-band >>-i<> --reporters=default --reporters=jest-junit environment: JEST_JUNIT_OUTPUT_DIR: tmp/test-results @@ -90,14 +94,16 @@ jobs: name: node version: '18.17.1' steps: - - test + - test: + run-in-band: true unit-electron28: executor: name: node version: '18.18.2' steps: - - test + - test: + run-in-band: true unit-electron29: executor: From 554bc7763d9c8935c2cf59eafd5967920b8eba87 Mon Sep 17 00:00:00 2001 From: Yuki Hattori Date: Wed, 1 Jan 2025 03:11:39 +0900 Subject: [PATCH 05/10] Update how to set parallel test on CI --- .circleci/config.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index edab66a8..51a2f057 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -45,9 +45,9 @@ commands: test: parameters: - run-in-band: + jest-parameters: type: boolean - default: false + default: --maxWorkers=2 steps: - checkout - install @@ -70,7 +70,7 @@ commands: - run: name: Jest - command: npm run test:unit:coverage -- --ci --maxWorkers=2 <<# parameters.run-in-band >>-i<> --reporters=default --reporters=jest-junit + command: npm run test:unit:coverage -- --ci --reporters=default --reporters=jest-junit << parameters.jest-parameters >> environment: JEST_JUNIT_OUTPUT_DIR: tmp/test-results @@ -95,7 +95,7 @@ jobs: version: '18.17.1' steps: - test: - run-in-band: true + jest-parameters: -i unit-electron28: executor: @@ -103,7 +103,7 @@ jobs: version: '18.18.2' steps: - test: - run-in-band: true + jest-parameters: -i unit-electron29: executor: From bbec3f0256fcb2543e059537935032098b05232d Mon Sep 17 00:00:00 2001 From: Yuki Hattori Date: Wed, 1 Jan 2025 03:13:49 +0900 Subject: [PATCH 06/10] Fix invalid CircleCI config --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 51a2f057..30a8cd48 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -46,7 +46,7 @@ commands: test: parameters: jest-parameters: - type: boolean + type: string default: --maxWorkers=2 steps: - checkout From e4c5800149ee7d1ee8bd1962f71b52aebe592c44 Mon Sep 17 00:00:00 2001 From: Yuki Hattori Date: Wed, 1 Jan 2025 03:42:11 +0900 Subject: [PATCH 07/10] Add --detectOpenHandles option to Jest command in CircleCI config --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 30a8cd48..81b1017b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -70,7 +70,7 @@ commands: - run: name: Jest - command: npm run test:unit:coverage -- --ci --reporters=default --reporters=jest-junit << parameters.jest-parameters >> + command: npm run test:unit:coverage -- --ci --reporters=default --reporters=jest-junit --detectOpenHandles << parameters.jest-parameters >> environment: JEST_JUNIT_OUTPUT_DIR: tmp/test-results From 5634ed3865be313ebde00e443adea4a293df6a25 Mon Sep 17 00:00:00 2001 From: Yuki Hattori Date: Wed, 1 Jan 2025 03:56:44 +0900 Subject: [PATCH 08/10] Mock Marp CLI when running the test for Marp CLI --- .circleci/config.yml | 12 +++--------- src/marp-cli.test.ts | 2 +- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 81b1017b..582ef42c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -44,10 +44,6 @@ commands: - run: npm run check:audit test: - parameters: - jest-parameters: - type: string - default: --maxWorkers=2 steps: - checkout - install @@ -70,7 +66,7 @@ commands: - run: name: Jest - command: npm run test:unit:coverage -- --ci --reporters=default --reporters=jest-junit --detectOpenHandles << parameters.jest-parameters >> + command: npm run test:unit:coverage -- --ci --maxWorkers=2 --reporters=default --reporters=jest-junit environment: JEST_JUNIT_OUTPUT_DIR: tmp/test-results @@ -94,16 +90,14 @@ jobs: name: node version: '18.17.1' steps: - - test: - jest-parameters: -i + - test unit-electron28: executor: name: node version: '18.18.2' steps: - - test: - jest-parameters: -i + - test unit-electron29: executor: diff --git a/src/marp-cli.test.ts b/src/marp-cli.test.ts index 6ae48e1a..0e710f49 100644 --- a/src/marp-cli.test.ts +++ b/src/marp-cli.test.ts @@ -27,7 +27,7 @@ describe('Marp CLI integration', () => { }) it('runs Marp CLI with passed args', async () => { - const marpCliSpy = jest.spyOn(marpCliModule, 'marpCli') + const marpCliSpy = jest.spyOn(marpCliModule, 'marpCli').mockResolvedValue(0) await runMarpCli(['--version']) expect(marpCliSpy).toHaveBeenCalledWith(['--version'], undefined) From 9813cf28134a229c5a01f0ed683b40986d74d608 Mon Sep 17 00:00:00 2001 From: Yuki Hattori Date: Wed, 1 Jan 2025 04:14:54 +0900 Subject: [PATCH 09/10] [ci skip] Update CHANGELOG.md --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e832115..943d7dc3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,10 +13,12 @@ ### Added - `markdown.marp.html` setting to control rendering HTML within Marp Markdown ([#476](https://github.com/marp-team/marp-vscode/pull/476)) +- `markdown.marp.browser` and `markdown.marp.browserPath` settings to control internally using browser to export ([#478](https://github.com/marp-team/marp-vscode/pull/478)) ### Deprecated -- `markdown.marp.enableHtml` setting ([#476](https://github.com/marp-team/marp-vscode/pull/476)) +- Deprecated `markdown.marp.enableHtml` setting in favor of `markdown.marp.html` ([#476](https://github.com/marp-team/marp-vscode/pull/476)) +- Deprecated `markdown.marp.chromePath` setting in favor of `markdown.marp.browserPath` ([#478](https://github.com/marp-team/marp-vscode/pull/478)) ### Changed From 11e5df194538fbe463d669704fe92df39b224f73 Mon Sep 17 00:00:00 2001 From: Yuki Hattori Date: Wed, 1 Jan 2025 04:24:48 +0900 Subject: [PATCH 10/10] [ci skip] Update CHANGELOG.md --- CHANGELOG.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 943d7dc3..67280c7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,17 +14,19 @@ - `markdown.marp.html` setting to control rendering HTML within Marp Markdown ([#476](https://github.com/marp-team/marp-vscode/pull/476)) - `markdown.marp.browser` and `markdown.marp.browserPath` settings to control internally using browser to export ([#478](https://github.com/marp-team/marp-vscode/pull/478)) - -### Deprecated - -- Deprecated `markdown.marp.enableHtml` setting in favor of `markdown.marp.html` ([#476](https://github.com/marp-team/marp-vscode/pull/476)) -- Deprecated `markdown.marp.chromePath` setting in favor of `markdown.marp.browserPath` ([#478](https://github.com/marp-team/marp-vscode/pull/478)) +- Support Firefox as a browser for exporting ([#473](https://github.com/marp-team/marp-vscode/pull/473), [#474](https://github.com/marp-team/marp-vscode/pull/474), [#478](https://github.com/marp-team/marp-vscode/pull/478)) ### Changed +- Several allowed HTML elements through Marp Core are enabled by default ([#472](https://github.com/marp-team/marp-vscode/pull/472), [#474](https://github.com/marp-team/marp-vscode/pull/474), [#476](https://github.com/marp-team/marp-vscode/pull/476)) - Upgrade development Node.js and dependent packages to the latest version ([#474](https://github.com/marp-team/marp-vscode/pull/474)) - Migrate ESLint config to flat config ([#475](https://github.com/marp-team/marp-vscode/pull/475)) +### Deprecated + +- Deprecated `markdown.marp.enableHtml` setting in favor of `markdown.marp.html` ([#476](https://github.com/marp-team/marp-vscode/pull/476)) +- Deprecated `markdown.marp.chromePath` setting in favor of `markdown.marp.browserPath` ([#478](https://github.com/marp-team/marp-vscode/pull/478)) + ## v2.8.0 - 2023-10-28 ### Changed