chore: read config file location from url params in ui mode
Reference https://github.com/microsoft/playwright/issues/29768
This commit is contained in:
parent
9e89f292bf
commit
72edf84c69
|
|
@ -105,7 +105,7 @@ export async function startTraceViewerServer(options?: TraceViewerServerOptions)
|
||||||
return server;
|
return server;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function installRootRedirect(server: HttpServer, traceUrls: string[], options: TraceViewerRedirectOptions) {
|
export async function installRootRedirect(server: HttpServer, traceUrls: string[], options: TraceViewerRedirectOptions & { resolvedConfigFile?: string }) {
|
||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
for (const traceUrl of traceUrls)
|
for (const traceUrl of traceUrls)
|
||||||
params.append('trace', traceUrl);
|
params.append('trace', traceUrl);
|
||||||
|
|
@ -115,6 +115,8 @@ export async function installRootRedirect(server: HttpServer, traceUrls: string[
|
||||||
params.append('isServer', '');
|
params.append('isServer', '');
|
||||||
if (isUnderTest())
|
if (isUnderTest())
|
||||||
params.append('isUnderTest', 'true');
|
params.append('isUnderTest', 'true');
|
||||||
|
if (options.resolvedConfigFile)
|
||||||
|
params.append('resolvedConfigFile', path.resolve(options.resolvedConfigFile));
|
||||||
for (const arg of options.args || [])
|
for (const arg of options.args || [])
|
||||||
params.append('arg', arg);
|
params.append('arg', arg);
|
||||||
if (options.grep)
|
if (options.grep)
|
||||||
|
|
|
||||||
|
|
@ -286,7 +286,16 @@ function validateProject(file: string, project: Project, title: string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function resolveConfigFile(configFileOrDirectory: string): string | undefined {
|
export function resolveConfigLocation(configFile: string | undefined): ConfigLocation {
|
||||||
|
const configFileOrDirectory = configFile ? path.resolve(process.cwd(), configFile) : process.cwd();
|
||||||
|
const resolvedConfigFile = resolveConfigFile(configFileOrDirectory);
|
||||||
|
return {
|
||||||
|
resolvedConfigFile,
|
||||||
|
configDir: resolvedConfigFile ? path.dirname(resolvedConfigFile) : configFileOrDirectory,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveConfigFile(configFileOrDirectory: string): string | undefined {
|
||||||
const resolveConfig = (configFile: string) => {
|
const resolveConfig = (configFile: string) => {
|
||||||
if (fs.existsSync(configFile))
|
if (fs.existsSync(configFile))
|
||||||
return configFile;
|
return configFile;
|
||||||
|
|
@ -309,22 +318,15 @@ export function resolveConfigFile(configFileOrDirectory: string): string | undef
|
||||||
return configFile;
|
return configFile;
|
||||||
// If there is no config, assume this as a root testing directory.
|
// If there is no config, assume this as a root testing directory.
|
||||||
return undefined;
|
return undefined;
|
||||||
} else {
|
|
||||||
// When passed a file, it must be a config file.
|
|
||||||
const configFile = resolveConfig(configFileOrDirectory);
|
|
||||||
return configFile!;
|
|
||||||
}
|
}
|
||||||
|
// When passed a file, it must be a config file.
|
||||||
|
return configFileOrDirectory!;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function loadConfigFromFileRestartIfNeeded(configFile: string | undefined, overrides?: ConfigCLIOverrides, ignoreDeps?: boolean): Promise<FullConfigInternal | null> {
|
export async function loadConfigFromFileRestartIfNeeded(configFile: string | undefined, overrides?: ConfigCLIOverrides, ignoreDeps?: boolean): Promise<FullConfigInternal | null> {
|
||||||
const configFileOrDirectory = configFile ? path.resolve(process.cwd(), configFile) : process.cwd();
|
const location = resolveConfigLocation(configFile);
|
||||||
const resolvedConfigFile = resolveConfigFile(configFileOrDirectory);
|
if (restartWithExperimentalTsEsm(location.resolvedConfigFile))
|
||||||
if (restartWithExperimentalTsEsm(resolvedConfigFile))
|
|
||||||
return null;
|
return null;
|
||||||
const location: ConfigLocation = {
|
|
||||||
configDir: resolvedConfigFile ? path.dirname(resolvedConfigFile) : configFileOrDirectory,
|
|
||||||
resolvedConfigFile,
|
|
||||||
};
|
|
||||||
return await loadConfig(location, overrides, ignoreDeps);
|
return await loadConfig(location, overrides, ignoreDeps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ import { ManualPromise, gracefullyProcessExitDoNotHang, isUnderTest } from 'play
|
||||||
import type { Transport, HttpServer } from 'playwright-core/lib/utils';
|
import type { Transport, HttpServer } from 'playwright-core/lib/utils';
|
||||||
import type * as reporterTypes from '../../types/testReporter';
|
import type * as reporterTypes from '../../types/testReporter';
|
||||||
import { collectAffectedTestFiles, dependenciesForTestFile } from '../transform/compilationCache';
|
import { collectAffectedTestFiles, dependenciesForTestFile } from '../transform/compilationCache';
|
||||||
import type { FullConfigInternal } from '../common/config';
|
import type { ConfigLocation, FullConfigInternal } from '../common/config';
|
||||||
import { InternalReporter } from '../reporters/internalReporter';
|
import { InternalReporter } from '../reporters/internalReporter';
|
||||||
import { createReporterForTestServer, createReporters } from './reporters';
|
import { createReporterForTestServer, createReporters } from './reporters';
|
||||||
import { TestRun, createTaskRunnerForList, createTaskRunnerForTestServer, createTaskRunnerForWatchSetup, createTaskRunnerForListFiles } from './tasks';
|
import { TestRun, createTaskRunnerForList, createTaskRunnerForTestServer, createTaskRunnerForWatchSetup, createTaskRunnerForListFiles } from './tasks';
|
||||||
|
|
@ -33,7 +33,7 @@ import { Watcher } from '../fsWatcher';
|
||||||
import type { ReportEntry, TestServerInterface, TestServerInterfaceEventEmitters } from '../isomorphic/testServerInterface';
|
import type { ReportEntry, TestServerInterface, TestServerInterfaceEventEmitters } from '../isomorphic/testServerInterface';
|
||||||
import { Runner } from './runner';
|
import { Runner } from './runner';
|
||||||
import type { ConfigCLIOverrides } from '../common/ipc';
|
import type { ConfigCLIOverrides } from '../common/ipc';
|
||||||
import { loadConfig, resolveConfigFile, restartWithExperimentalTsEsm } from '../common/configLoader';
|
import { loadConfig, resolveConfigLocation, restartWithExperimentalTsEsm } from '../common/configLoader';
|
||||||
import { webServerPluginsForConfig } from '../plugins/webServerPlugin';
|
import { webServerPluginsForConfig } from '../plugins/webServerPlugin';
|
||||||
import type { TraceViewerRedirectOptions, TraceViewerServerOptions } from 'playwright-core/lib/server/trace/viewer/traceViewer';
|
import type { TraceViewerRedirectOptions, TraceViewerServerOptions } from 'playwright-core/lib/server/trace/viewer/traceViewer';
|
||||||
import type { TestRunnerPluginRegistration } from '../plugins';
|
import type { TestRunnerPluginRegistration } from '../plugins';
|
||||||
|
|
@ -44,15 +44,15 @@ const originalStdoutWrite = process.stdout.write;
|
||||||
const originalStderrWrite = process.stderr.write;
|
const originalStderrWrite = process.stderr.write;
|
||||||
|
|
||||||
class TestServer {
|
class TestServer {
|
||||||
private _configFile: string | undefined;
|
private _configLocation: ConfigLocation;
|
||||||
private _dispatcher: TestServerDispatcher | undefined;
|
private _dispatcher: TestServerDispatcher | undefined;
|
||||||
|
|
||||||
constructor(configFile: string | undefined) {
|
constructor(configLocation: ConfigLocation) {
|
||||||
this._configFile = configFile;
|
this._configLocation = configLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
async start(options: { host?: string, port?: number }): Promise<HttpServer> {
|
async start(options: { host?: string, port?: number }): Promise<HttpServer> {
|
||||||
this._dispatcher = new TestServerDispatcher(this._configFile);
|
this._dispatcher = new TestServerDispatcher(this._configLocation);
|
||||||
return await startTraceViewerServer({ ...options, transport: this._dispatcher.transport });
|
return await startTraceViewerServer({ ...options, transport: this._dispatcher.transport });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -63,7 +63,7 @@ class TestServer {
|
||||||
}
|
}
|
||||||
|
|
||||||
class TestServerDispatcher implements TestServerInterface {
|
class TestServerDispatcher implements TestServerInterface {
|
||||||
private _configFile: string | undefined;
|
private _configLocation: ConfigLocation;
|
||||||
private _globalWatcher: Watcher;
|
private _globalWatcher: Watcher;
|
||||||
private _testWatcher: Watcher;
|
private _testWatcher: Watcher;
|
||||||
private _testRun: { run: Promise<reporterTypes.FullResult['status']>, stop: ManualPromise<void> } | undefined;
|
private _testRun: { run: Promise<reporterTypes.FullResult['status']>, stop: ManualPromise<void> } | undefined;
|
||||||
|
|
@ -77,8 +77,8 @@ class TestServerDispatcher implements TestServerInterface {
|
||||||
private _closeOnDisconnect = false;
|
private _closeOnDisconnect = false;
|
||||||
private _devServerHandle: (() => Promise<void>) | undefined;
|
private _devServerHandle: (() => Promise<void>) | undefined;
|
||||||
|
|
||||||
constructor(configFile: string | undefined) {
|
constructor(configLocation: ConfigLocation) {
|
||||||
this._configFile = configFile;
|
this._configLocation = configLocation;
|
||||||
this.transport = {
|
this.transport = {
|
||||||
dispatch: (method, params) => (this as any)[method](params),
|
dispatch: (method, params) => (this as any)[method](params),
|
||||||
onclose: () => {
|
onclose: () => {
|
||||||
|
|
@ -145,7 +145,7 @@ class TestServerDispatcher implements TestServerInterface {
|
||||||
await this.runGlobalTeardown();
|
await this.runGlobalTeardown();
|
||||||
|
|
||||||
const { reporter, report } = await this._collectingReporter();
|
const { reporter, report } = await this._collectingReporter();
|
||||||
const { config, error } = await this._loadConfig(this._configFile);
|
const { config, error } = await this._loadConfig();
|
||||||
if (!config) {
|
if (!config) {
|
||||||
reporter.onError(error!);
|
reporter.onError(error!);
|
||||||
return { status: 'failed', report };
|
return { status: 'failed', report };
|
||||||
|
|
@ -178,7 +178,7 @@ class TestServerDispatcher implements TestServerInterface {
|
||||||
if (this._devServerHandle)
|
if (this._devServerHandle)
|
||||||
return { status: 'failed', report: [] };
|
return { status: 'failed', report: [] };
|
||||||
const { reporter, report } = await this._collectingReporter();
|
const { reporter, report } = await this._collectingReporter();
|
||||||
const { config, error } = await this._loadConfig(this._configFile);
|
const { config, error } = await this._loadConfig();
|
||||||
if (!config) {
|
if (!config) {
|
||||||
reporter.onError(error!);
|
reporter.onError(error!);
|
||||||
return { status: 'failed', report };
|
return { status: 'failed', report };
|
||||||
|
|
@ -212,14 +212,14 @@ class TestServerDispatcher implements TestServerInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
async clearCache(params: Parameters<TestServerInterface['clearCache']>[0]): ReturnType<TestServerInterface['clearCache']> {
|
async clearCache(params: Parameters<TestServerInterface['clearCache']>[0]): ReturnType<TestServerInterface['clearCache']> {
|
||||||
const { config } = await this._loadConfig(this._configFile);
|
const { config } = await this._loadConfig();
|
||||||
if (config)
|
if (config)
|
||||||
await clearCacheAndLogToConsole(config);
|
await clearCacheAndLogToConsole(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
async listFiles(params: Parameters<TestServerInterface['listFiles']>[0]): ReturnType<TestServerInterface['listFiles']> {
|
async listFiles(params: Parameters<TestServerInterface['listFiles']>[0]): ReturnType<TestServerInterface['listFiles']> {
|
||||||
const { reporter, report } = await this._collectingReporter();
|
const { reporter, report } = await this._collectingReporter();
|
||||||
const { config, error } = await this._loadConfig(this._configFile);
|
const { config, error } = await this._loadConfig();
|
||||||
if (!config) {
|
if (!config) {
|
||||||
reporter.onError(error!);
|
reporter.onError(error!);
|
||||||
return { status: 'failed', report };
|
return { status: 'failed', report };
|
||||||
|
|
@ -250,7 +250,7 @@ class TestServerDispatcher implements TestServerInterface {
|
||||||
retries: 0,
|
retries: 0,
|
||||||
};
|
};
|
||||||
const { reporter, report } = await this._collectingReporter();
|
const { reporter, report } = await this._collectingReporter();
|
||||||
const { config, error } = await this._loadConfig(this._configFile, overrides);
|
const { config, error } = await this._loadConfig(overrides);
|
||||||
if (!config) {
|
if (!config) {
|
||||||
reporter.onError(error!);
|
reporter.onError(error!);
|
||||||
return { report: [], status: 'failed' };
|
return { report: [], status: 'failed' };
|
||||||
|
|
@ -315,7 +315,7 @@ class TestServerDispatcher implements TestServerInterface {
|
||||||
else
|
else
|
||||||
process.env.PW_LIVE_TRACE_STACKS = undefined;
|
process.env.PW_LIVE_TRACE_STACKS = undefined;
|
||||||
|
|
||||||
const { config, error } = await this._loadConfig(this._configFile, overrides);
|
const { config, error } = await this._loadConfig(overrides);
|
||||||
if (!config) {
|
if (!config) {
|
||||||
const wireReporter = await this._wireReporter(e => this._dispatchEvent('report', e));
|
const wireReporter = await this._wireReporter(e => this._dispatchEvent('report', e));
|
||||||
wireReporter.onError(error!);
|
wireReporter.onError(error!);
|
||||||
|
|
@ -359,7 +359,7 @@ class TestServerDispatcher implements TestServerInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
async findRelatedTestFiles(params: Parameters<TestServerInterface['findRelatedTestFiles']>[0]): ReturnType<TestServerInterface['findRelatedTestFiles']> {
|
async findRelatedTestFiles(params: Parameters<TestServerInterface['findRelatedTestFiles']>[0]): ReturnType<TestServerInterface['findRelatedTestFiles']> {
|
||||||
const { config, error } = await this._loadConfig(this._configFile);
|
const { config, error } = await this._loadConfig();
|
||||||
if (error)
|
if (error)
|
||||||
return { testFiles: [], errors: [error] };
|
return { testFiles: [], errors: [error] };
|
||||||
const runner = new Runner(config!);
|
const runner = new Runner(config!);
|
||||||
|
|
@ -393,11 +393,9 @@ class TestServerDispatcher implements TestServerInterface {
|
||||||
gracefullyProcessExitDoNotHang(0);
|
gracefullyProcessExitDoNotHang(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _loadConfig(configFile: string | undefined, overrides?: ConfigCLIOverrides): Promise<{ config: FullConfigInternal | null, error?: reporterTypes.TestError }> {
|
private async _loadConfig(overrides?: ConfigCLIOverrides): Promise<{ config: FullConfigInternal | null, error?: reporterTypes.TestError }> {
|
||||||
const configFileOrDirectory = configFile ? path.resolve(process.cwd(), configFile) : process.cwd();
|
|
||||||
const resolvedConfigFile = resolveConfigFile(configFileOrDirectory);
|
|
||||||
try {
|
try {
|
||||||
const config = await loadConfig({ resolvedConfigFile, configDir: resolvedConfigFile === configFileOrDirectory ? path.dirname(resolvedConfigFile) : configFileOrDirectory }, overrides);
|
const config = await loadConfig(this._configLocation, overrides);
|
||||||
// Preserve plugin instances between setup and build.
|
// Preserve plugin instances between setup and build.
|
||||||
if (!this._plugins)
|
if (!this._plugins)
|
||||||
this._plugins = config.plugins || [];
|
this._plugins = config.plugins || [];
|
||||||
|
|
@ -411,8 +409,8 @@ class TestServerDispatcher implements TestServerInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function runUIMode(configFile: string | undefined, options: TraceViewerServerOptions & TraceViewerRedirectOptions): Promise<reporterTypes.FullResult['status'] | 'restarted'> {
|
export async function runUIMode(configFile: string | undefined, options: TraceViewerServerOptions & TraceViewerRedirectOptions): Promise<reporterTypes.FullResult['status'] | 'restarted'> {
|
||||||
return await innerRunTestServer(configFile, options, async (server: HttpServer, cancelPromise: ManualPromise<void>) => {
|
return await innerRunTestServer(configFile, options, async (server: HttpServer, cancelPromise: ManualPromise<void>, configLocation: ConfigLocation) => {
|
||||||
await installRootRedirect(server, [], { ...options, webApp: 'uiMode.html' });
|
await installRootRedirect(server, [], { ...options, webApp: 'uiMode.html', resolvedConfigFile: configLocation.resolvedConfigFile });
|
||||||
if (options.host !== undefined || options.port !== undefined) {
|
if (options.host !== undefined || options.port !== undefined) {
|
||||||
await openTraceInBrowser(server.urlPrefix());
|
await openTraceInBrowser(server.urlPrefix());
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -434,17 +432,18 @@ export async function runTestServer(configFile: string | undefined, options: { h
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function innerRunTestServer(configFile: string | undefined, options: { host?: string, port?: number }, openUI: (server: HttpServer, cancelPromise: ManualPromise<void>) => Promise<void>): Promise<reporterTypes.FullResult['status'] | 'restarted'> {
|
async function innerRunTestServer(configFile: string | undefined, options: { host?: string, port?: number }, openUI: (server: HttpServer, cancelPromise: ManualPromise<void>, configLocation: ConfigLocation) => Promise<void>): Promise<reporterTypes.FullResult['status'] | 'restarted'> {
|
||||||
if (restartWithExperimentalTsEsm(undefined, true))
|
if (restartWithExperimentalTsEsm(undefined, true))
|
||||||
return 'restarted';
|
return 'restarted';
|
||||||
const testServer = new TestServer(configFile);
|
const configLocation = resolveConfigLocation(configFile);
|
||||||
|
const testServer = new TestServer(configLocation);
|
||||||
const cancelPromise = new ManualPromise<void>();
|
const cancelPromise = new ManualPromise<void>();
|
||||||
const sigintWatcher = new SigIntWatcher();
|
const sigintWatcher = new SigIntWatcher();
|
||||||
process.stdin.on('close', () => gracefullyProcessExitDoNotHang(0));
|
process.stdin.on('close', () => gracefullyProcessExitDoNotHang(0));
|
||||||
void sigintWatcher.promise().then(() => cancelPromise.resolve());
|
void sigintWatcher.promise().then(() => cancelPromise.resolve());
|
||||||
try {
|
try {
|
||||||
const server = await testServer.start(options);
|
const server = await testServer.start(options);
|
||||||
await openUI(server, cancelPromise);
|
await openUI(server, cancelPromise, configLocation);
|
||||||
await cancelPromise;
|
await cancelPromise;
|
||||||
} finally {
|
} finally {
|
||||||
await testServer.stop();
|
await testServer.stop();
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ import '@web/third_party/vscode/codicon.css';
|
||||||
import { settings } from '@web/uiUtils';
|
import { settings } from '@web/uiUtils';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import './uiModeFiltersView.css';
|
import './uiModeFiltersView.css';
|
||||||
import type { TestModel } from './uiModeModel';
|
|
||||||
|
|
||||||
export const FiltersView: React.FC<{
|
export const FiltersView: React.FC<{
|
||||||
filterText: string;
|
filterText: string;
|
||||||
|
|
@ -29,9 +28,9 @@ export const FiltersView: React.FC<{
|
||||||
setStatusFilters: (filters: Map<string, boolean>) => void;
|
setStatusFilters: (filters: Map<string, boolean>) => void;
|
||||||
projectFilters: Map<string, boolean>;
|
projectFilters: Map<string, boolean>;
|
||||||
setProjectFilters: (filters: Map<string, boolean>) => void;
|
setProjectFilters: (filters: Map<string, boolean>) => void;
|
||||||
testModel: TestModel | undefined,
|
resolvedConfigFile: string | undefined,
|
||||||
runTests: () => void;
|
runTests: () => void;
|
||||||
}> = ({ filterText, setFilterText, statusFilters, setStatusFilters, projectFilters, setProjectFilters, testModel, runTests }) => {
|
}> = ({ filterText, setFilterText, statusFilters, setStatusFilters, projectFilters, setProjectFilters, resolvedConfigFile, runTests }) => {
|
||||||
const [expanded, setExpanded] = React.useState(false);
|
const [expanded, setExpanded] = React.useState(false);
|
||||||
const inputRef = React.useRef<HTMLInputElement>(null);
|
const inputRef = React.useRef<HTMLInputElement>(null);
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
|
|
@ -80,9 +79,8 @@ export const FiltersView: React.FC<{
|
||||||
const copy = new Map(projectFilters);
|
const copy = new Map(projectFilters);
|
||||||
copy.set(projectName, !copy.get(projectName));
|
copy.set(projectName, !copy.get(projectName));
|
||||||
setProjectFilters(copy);
|
setProjectFilters(copy);
|
||||||
const configFile = testModel?.config?.configFile;
|
if (resolvedConfigFile)
|
||||||
if (configFile)
|
settings.setObject(resolvedConfigFile + ':projects', [...copy.entries()].filter(([_, v]) => v).map(([k]) => k));
|
||||||
settings.setObject(configFile + ':projects', [...copy.entries()].filter(([_, v]) => v).map(([k]) => k));
|
|
||||||
}}/>
|
}}/>
|
||||||
<div>{projectName || 'untitled'}</div>
|
<div>{projectName || 'untitled'}</div>
|
||||||
</label>
|
</label>
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ const guid = searchParams.get('ws');
|
||||||
const wsURL = new URL(`../${guid}`, window.location.toString());
|
const wsURL = new URL(`../${guid}`, window.location.toString());
|
||||||
wsURL.protocol = (window.location.protocol === 'https:' ? 'wss:' : 'ws:');
|
wsURL.protocol = (window.location.protocol === 'https:' ? 'wss:' : 'ws:');
|
||||||
const queryParams = {
|
const queryParams = {
|
||||||
|
resolvedConfigFile: searchParams.get('resolvedConfigFile') || undefined,
|
||||||
args: searchParams.getAll('arg'),
|
args: searchParams.getAll('arg'),
|
||||||
grep: searchParams.get('grep') || undefined,
|
grep: searchParams.get('grep') || undefined,
|
||||||
grepInvert: searchParams.get('grepInvert') || undefined,
|
grepInvert: searchParams.get('grepInvert') || undefined,
|
||||||
|
|
@ -201,8 +202,8 @@ export const UIModeView: React.FC<{}> = ({
|
||||||
if (!testModel)
|
if (!testModel)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const { config, rootSuite } = testModel;
|
const { rootSuite } = testModel;
|
||||||
const selectedProjects = config.configFile ? settings.getObject<string[] | undefined>(config.configFile + ':projects', undefined) : undefined;
|
const selectedProjects = queryParams.resolvedConfigFile ? settings.getObject<string[] | undefined>(queryParams.resolvedConfigFile + ':projects', undefined) : undefined;
|
||||||
const newFilter = new Map(projectFilters);
|
const newFilter = new Map(projectFilters);
|
||||||
for (const projectName of newFilter.keys()) {
|
for (const projectName of newFilter.keys()) {
|
||||||
if (!rootSuite.suites.find(s => s.title === projectName))
|
if (!rootSuite.suites.find(s => s.title === projectName))
|
||||||
|
|
@ -411,7 +412,7 @@ export const UIModeView: React.FC<{}> = ({
|
||||||
setStatusFilters={setStatusFilters}
|
setStatusFilters={setStatusFilters}
|
||||||
projectFilters={projectFilters}
|
projectFilters={projectFilters}
|
||||||
setProjectFilters={setProjectFilters}
|
setProjectFilters={setProjectFilters}
|
||||||
testModel={testModel}
|
resolvedConfigFile={queryParams.resolvedConfigFile}
|
||||||
runTests={() => runTests('bounce-if-busy', visibleTestIds)} />
|
runTests={() => runTests('bounce-if-busy', visibleTestIds)} />
|
||||||
<Toolbar noMinHeight={true}>
|
<Toolbar noMinHeight={true}>
|
||||||
{!isRunningTest && !progress && <div className='section-title'>Tests</div>}
|
{!isRunningTest && !progress && <div className='section-title'>Tests</div>}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue