-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add per-project browser config processing (#81)
* Add browser-specific configuration helpers to process custom launcher and debugger configurations Update extension config generation to load from project karma config files * Fix chrome's debugger flag to avoid it not starting Add user prefs to configure firefox to allow dev tools connections * Update browser helper classes to implement an interface, rather than extend an abstract base class Update the config helper to avoid loading the karma config during configuration Update the config helper to look for the browser type for custom launch configs to determine if they are supported Update the karma config loader to use custom launcher configuration from the user's karma config if a matching config was found and it isn't overriden in settings * Fix vscode test debugging config Add checks to ensure the custom launcher type is supported when compiling launcher configuration Update the electron helper to extend the chrome helper Update extension config tests to cover new browser/custom launcher config processing * Update to require at least one supported browser for each browser helper Update to pass config values to the browser helper rather than the whole config store Update to clone the custom launcher when adding debug configuration, rather than modifying in place * Update to check incoming browser type when creating a default launcher config in all helpers Update to check if the custom launcher base is supported as the first step in all custom launchers
- Loading branch information
Showing
15 changed files
with
1,032 additions
and
73 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { BrowserHelper } from './browser-helper.js'; | ||
import { ChromeBrowserHelper } from './chrome-helper.js'; | ||
import { ElectronBrowserHelper } from './electron-helper.js'; | ||
import { FirefoxBrowserHelper } from './firefox-helper.js'; | ||
import { MsEdgeBrowserHelper } from './msedge-helper.js'; | ||
|
||
export class BrowserHelperFactory { | ||
static BROWSER_HELPER_INSTANCES = [ | ||
new ChromeBrowserHelper(), | ||
new FirefoxBrowserHelper(), | ||
new MsEdgeBrowserHelper(), | ||
new ElectronBrowserHelper() | ||
]; | ||
|
||
public static getBrowserHelper(browserType: string): BrowserHelper { | ||
return ( | ||
this.BROWSER_HELPER_INSTANCES.find(helper => helper.isSupportedBrowser(browserType)) ?? | ||
this.BROWSER_HELPER_INSTANCES[0] | ||
); | ||
} | ||
|
||
public static isSupportedBrowser(browserType: string): boolean { | ||
return this.BROWSER_HELPER_INSTANCES.some(helper => helper.isSupportedBrowser(browserType)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { DebugConfiguration } from 'vscode'; | ||
|
||
import { CustomLauncher } from 'karma'; | ||
|
||
import { ContainerMode } from '../extension-config.js'; | ||
|
||
export interface BrowserHelper { | ||
supportedBrowsers: [string, ...string[]]; | ||
debuggerType: string; | ||
debuggingPortFlag: string; | ||
|
||
getCustomLauncher( | ||
browserType: string, | ||
customLaucher: CustomLauncher | undefined, | ||
configuredContainerMode: ContainerMode | undefined, | ||
isNonHeadlessMode: boolean | ||
): CustomLauncher; | ||
|
||
isSupportedBrowser(browserType: string): boolean; | ||
|
||
getDefaultDebuggerConfig(): DebugConfiguration; | ||
|
||
addCustomLauncherDebugPort(customLaucher: CustomLauncher, debugPort: number | undefined): CustomLauncher | undefined; | ||
|
||
getDefaultDebugPort( | ||
customLauncher: Readonly<CustomLauncher>, | ||
debuggerConfig: Readonly<DebugConfiguration> | ||
): number | undefined; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
import { DebugConfiguration } from 'vscode'; | ||
|
||
import { CustomLauncher } from 'karma'; | ||
|
||
import { isContainerModeEnabled } from '../config-helper.js'; | ||
import { ContainerMode } from '../extension-config.js'; | ||
import { BrowserHelper } from './browser-helper.js'; | ||
|
||
export class ChromeBrowserHelper implements BrowserHelper { | ||
public static DEFAULT_DEBUGGING_PORT: number | undefined = 9222; | ||
private static NO_SANDBOX_FLAG: string = '--no-sandbox'; | ||
private static HEADLESS_FLAGS: string[] = ['--headless', '--disable-gpu', '--disable-dev-shm-usage']; | ||
|
||
public get supportedBrowsers(): [string, ...string[]] { | ||
return ['Chrome', 'Chromium', 'Dartium']; | ||
} | ||
public get debuggerType(): string { | ||
return 'chrome'; | ||
} | ||
public get debuggingPortFlag(): string { | ||
return '--remote-debugging-port'; | ||
} | ||
|
||
public getCustomLauncher( | ||
browserType: string, | ||
customLaucher: CustomLauncher | undefined, | ||
configuredContainerMode: ContainerMode | undefined, | ||
isNonHeadlessMode: boolean | ||
): CustomLauncher { | ||
if (customLaucher && !this.isSupportedBrowser(customLaucher.base)) { | ||
return customLaucher; | ||
} | ||
|
||
const configuredLauncher: CustomLauncher = customLaucher ?? { | ||
base: this.isSupportedBrowser(browserType) ? browserType : this.supportedBrowsers[0], | ||
flags: [ | ||
...ChromeBrowserHelper.HEADLESS_FLAGS, | ||
`${this.debuggingPortFlag}=${ChromeBrowserHelper.DEFAULT_DEBUGGING_PORT}` | ||
] | ||
}; | ||
|
||
const isContainerMode = isContainerModeEnabled(configuredContainerMode); | ||
let launcherFlags = (configuredLauncher.flags ??= []); | ||
|
||
if (isContainerMode && !launcherFlags.includes(ChromeBrowserHelper.NO_SANDBOX_FLAG)) { | ||
launcherFlags = [...launcherFlags, ChromeBrowserHelper.NO_SANDBOX_FLAG]; | ||
} | ||
|
||
if (!isContainerMode && !configuredLauncher.base.includes('Headless') && isNonHeadlessMode) { | ||
launcherFlags = launcherFlags.filter(flag => !ChromeBrowserHelper.HEADLESS_FLAGS.includes(flag)); | ||
} | ||
|
||
const customLauncher: CustomLauncher = { ...configuredLauncher, flags: launcherFlags }; | ||
return customLauncher; | ||
} | ||
|
||
public isSupportedBrowser(browserType: string): boolean { | ||
return this.supportedBrowsers.some(supportedBrowser => browserType.startsWith(supportedBrowser)); | ||
} | ||
|
||
public getDefaultDebuggerConfig(): DebugConfiguration { | ||
return { | ||
name: 'Karma Test Explorer Debugging', | ||
type: this.debuggerType, | ||
request: 'attach', | ||
browserAttachLocation: 'workspace', | ||
address: 'localhost', | ||
port: ChromeBrowserHelper.DEFAULT_DEBUGGING_PORT, | ||
timeout: 60000 | ||
}; | ||
} | ||
|
||
public addCustomLauncherDebugPort( | ||
customLaucher: CustomLauncher, | ||
debugPort: number | undefined | ||
): CustomLauncher | undefined { | ||
if (!customLaucher || debugPort === undefined) { | ||
return; | ||
} | ||
|
||
return { | ||
...customLaucher, | ||
flags: customLaucher.flags?.map(flag => | ||
flag.startsWith(this.debuggingPortFlag) ? `${this.debuggingPortFlag}=${debugPort}` : flag | ||
) | ||
}; | ||
} | ||
|
||
public getDefaultDebugPort( | ||
customLauncher: Readonly<CustomLauncher>, | ||
debuggerConfig: Readonly<DebugConfiguration> | ||
): number | undefined { | ||
const isSupportedLaunchType = this.supportedBrowsers.some(browser => customLauncher.base.startsWith(browser)); | ||
const isSupportedDebugConfig = debuggerConfig.type === this.debuggerType; | ||
if (!isSupportedLaunchType || !isSupportedDebugConfig) { | ||
return undefined; | ||
} | ||
|
||
let configuredPort: number | undefined; | ||
const browserDebugPortFlag = customLauncher.flags?.find(flag => flag.startsWith(this.debuggingPortFlag)); | ||
|
||
if (browserDebugPortFlag) { | ||
const portPosition = browserDebugPortFlag.search(/[0-9]+$/g); | ||
const portString = portPosition !== -1 ? browserDebugPortFlag.substring(portPosition) : undefined; | ||
configuredPort = portString ? parseInt(portString, 10) : undefined; | ||
} | ||
|
||
return configuredPort ?? ChromeBrowserHelper.DEFAULT_DEBUGGING_PORT; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { CustomLauncher } from 'karma'; | ||
|
||
import { isContainerModeEnabled } from '../config-helper.js'; | ||
import { ContainerMode } from '../extension-config.js'; | ||
import { ChromeBrowserHelper } from './chrome-helper.js'; | ||
|
||
export class ElectronBrowserHelper extends ChromeBrowserHelper { | ||
public override get supportedBrowsers(): [string, ...string[]] { | ||
return ['Electron']; | ||
} | ||
|
||
public override getCustomLauncher( | ||
browserType: string, | ||
customLaucher: CustomLauncher | undefined, | ||
configuredContainerMode: ContainerMode | undefined, | ||
isNonHeadlessMode: boolean | ||
): CustomLauncher { | ||
if (customLaucher && !this.isSupportedBrowser(customLaucher.base)) { | ||
return customLaucher; | ||
} | ||
|
||
const configuredLauncher: CustomLauncher = customLaucher ?? { | ||
base: this.isSupportedBrowser(browserType) ? browserType : this.supportedBrowsers[0], | ||
flags: [`${this.debuggingPortFlag}=${ElectronBrowserHelper.DEFAULT_DEBUGGING_PORT}`] | ||
}; | ||
|
||
const isContainerMode = isContainerModeEnabled(configuredContainerMode); | ||
|
||
if (!isContainerMode && isNonHeadlessMode) { | ||
const browserWindowOptions = ((configuredLauncher as any).browserWindowOptions ??= {}); | ||
browserWindowOptions.webPreferences ??= {}; | ||
browserWindowOptions.webPreferences.show = true; | ||
} | ||
|
||
return configuredLauncher; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
import { DebugConfiguration } from 'vscode'; | ||
|
||
import { CustomLauncher } from 'karma'; | ||
|
||
import { isContainerModeEnabled } from '../config-helper.js'; | ||
import { ContainerMode } from '../extension-config.js'; | ||
import { BrowserHelper } from './browser-helper.js'; | ||
|
||
export class FirefoxBrowserHelper implements BrowserHelper { | ||
public static DEFAULT_DEBUGGING_PORT: number | undefined = 9222; | ||
private static HEADLESS_FLAGS: string[] = ['-headless']; | ||
|
||
public get supportedBrowsers(): [string, ...string[]] { | ||
return ['Firefox']; | ||
} | ||
public get debuggerType(): string { | ||
return 'firefox'; | ||
} | ||
public get debuggingPortFlag(): string { | ||
return '-start-debugger-server'; | ||
} | ||
|
||
public getCustomLauncher( | ||
browserType: string, | ||
customLaucher: CustomLauncher | undefined, | ||
configuredContainerMode: ContainerMode | undefined, | ||
isNonHeadlessMode: boolean | ||
): CustomLauncher { | ||
if (customLaucher && !this.isSupportedBrowser(customLaucher.base)) { | ||
return customLaucher; | ||
} | ||
|
||
const configuredLauncher: CustomLauncher = | ||
customLaucher ?? | ||
({ | ||
base: this.isSupportedBrowser(browserType) ? browserType : this.supportedBrowsers[0], | ||
flags: [ | ||
...FirefoxBrowserHelper.HEADLESS_FLAGS, | ||
`${this.debuggingPortFlag} ${FirefoxBrowserHelper.DEFAULT_DEBUGGING_PORT}` | ||
], | ||
prefs: { | ||
'devtools.debugger.remote-enabled': true, | ||
'devtools.chrome.enabled': true, | ||
'devtools.debugger.prompt-connection': false | ||
} | ||
} as any); | ||
|
||
const isContainerMode = isContainerModeEnabled(configuredContainerMode); | ||
let launcherFlags = (configuredLauncher.flags ??= []); | ||
|
||
if (!isContainerMode && !configuredLauncher.base.includes('Headless') && isNonHeadlessMode) { | ||
launcherFlags = launcherFlags.filter(flag => !FirefoxBrowserHelper.HEADLESS_FLAGS.includes(flag)); | ||
} | ||
|
||
const customLauncher: CustomLauncher = { ...configuredLauncher, flags: launcherFlags }; | ||
return customLauncher; | ||
} | ||
|
||
public isSupportedBrowser(browserType: string): boolean { | ||
return this.supportedBrowsers.some(supportedBrowser => browserType.startsWith(supportedBrowser)); | ||
} | ||
|
||
public getDefaultDebuggerConfig(): DebugConfiguration { | ||
return { | ||
name: 'Karma Test Explorer Debugging', | ||
type: this.debuggerType, | ||
request: 'attach', | ||
browserAttachLocation: 'workspace', | ||
address: 'localhost', | ||
port: FirefoxBrowserHelper.DEFAULT_DEBUGGING_PORT, | ||
timeout: 60000 | ||
}; | ||
} | ||
|
||
public addCustomLauncherDebugPort( | ||
customLaucher: CustomLauncher, | ||
debugPort: number | undefined | ||
): CustomLauncher | undefined { | ||
if (!customLaucher || debugPort === undefined) { | ||
return undefined; | ||
} | ||
|
||
return { | ||
...customLaucher, | ||
flags: customLaucher.flags?.map(flag => | ||
flag.startsWith(this.debuggingPortFlag) ? `${this.debuggingPortFlag} ${debugPort}` : flag | ||
) | ||
}; | ||
} | ||
|
||
public getDefaultDebugPort( | ||
customLauncher: Readonly<CustomLauncher>, | ||
debuggerConfig: Readonly<DebugConfiguration> | ||
): number | undefined { | ||
const isSupportedLaunchType = this.supportedBrowsers.some(browser => customLauncher.base.startsWith(browser)); | ||
const isSupportedDebugConfig = debuggerConfig.type === this.debuggerType; | ||
if (!isSupportedLaunchType || !isSupportedDebugConfig) { | ||
return undefined; | ||
} | ||
|
||
let configuredPort: number | undefined; | ||
const browserDebugPortFlag = customLauncher.flags?.find(flag => flag.startsWith(this.debuggingPortFlag)); | ||
|
||
if (browserDebugPortFlag) { | ||
const portPosition = browserDebugPortFlag.search(/[0-9]+$/g); | ||
const portString = portPosition !== -1 ? browserDebugPortFlag.substring(portPosition) : undefined; | ||
configuredPort = portString ? parseInt(portString, 10) : undefined; | ||
} | ||
|
||
return configuredPort ?? FirefoxBrowserHelper.DEFAULT_DEBUGGING_PORT; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { ChromeBrowserHelper } from './chrome-helper.js'; | ||
|
||
export class MsEdgeBrowserHelper extends ChromeBrowserHelper { | ||
public override get supportedBrowsers(): [string, ...string[]] { | ||
return ['Edge']; | ||
} | ||
public override get debuggerType(): string { | ||
return 'msedge'; | ||
} | ||
} |
Oops, something went wrong.