From 17b9217a6612087b99cacf5be4aeffc7b0886f99 Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Wed, 18 Oct 2023 16:19:49 -0700 Subject: [PATCH] fix(win): normalize fs paths using vscode.Uri (#386) --- src/debugHighlight.ts | 2 +- src/extension.ts | 3 +-- src/oopReporter.ts | 4 ++-- src/playwrightTest.ts | 7 +++---- src/reporterServer.ts | 36 +++++++++++++++++++++++++++++------- src/testModel.ts | 3 +-- src/testTree.ts | 3 +-- 7 files changed, 38 insertions(+), 20 deletions(-) diff --git a/src/debugHighlight.ts b/src/debugHighlight.ts index 52ec94f5c..db867cf97 100644 --- a/src/debugHighlight.ts +++ b/src/debugHighlight.ts @@ -17,7 +17,7 @@ import { locatorForSourcePosition, pruneAstCaches } from './babelHighlightUtil'; import { debugSessionName } from './debugSessionName'; import { replaceActionWithLocator, locatorMethodRegex } from './methodNames'; -import type { Location } from './reporter'; +import type { Location } from './oopReporter'; import { ReusedBrowser } from './reusedBrowser'; import * as vscodeTypes from './vscodeTypes'; diff --git a/src/extension.ts b/src/extension.ts index 65f30a17b..fd3cf3d74 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -19,9 +19,8 @@ import StackUtils from 'stack-utils'; import { DebugHighlight } from './debugHighlight'; import { installBrowsers, installPlaywright } from './installer'; import { MultiMap } from './multimap'; -import { Entry } from './oopReporter'; import { PlaywrightTest, TestListener } from './playwrightTest'; -import type { Location, TestError } from './reporter'; +import type { Location, TestError, Entry } from './oopReporter'; import { ReusedBrowser } from './reusedBrowser'; import { SettingsModel } from './settingsModel'; import { SettingsView } from './settingsView'; diff --git a/src/oopReporter.ts b/src/oopReporter.ts index c33a6d16c..d4ee5485d 100644 --- a/src/oopReporter.ts +++ b/src/oopReporter.ts @@ -17,7 +17,9 @@ import type { FullConfig, FullProject, FullResult, Location, Reporter, Suite, TestCase, TestError, TestResult, TestStatus, TestStep } from './reporter'; import { ConnectionTransport, WebSocketTransport } from './transport'; +export type { TestError, Location } from './reporter'; export type EntryType = 'project' | 'file' | 'suite' | 'test'; + export type Entry = { type: EntryType; title: string; @@ -60,8 +62,6 @@ export type StepEndParams = { }; class OopReporter implements Reporter { - config!: FullConfig; - suite!: Suite; private _transport: Promise; constructor() { diff --git a/src/playwrightTest.ts b/src/playwrightTest.ts index bf45e6ecb..d809f7f6f 100644 --- a/src/playwrightTest.ts +++ b/src/playwrightTest.ts @@ -18,8 +18,7 @@ import { spawn } from 'child_process'; import path from 'path'; import { debugSessionName } from './debugSessionName'; import { ConfigListFilesReport } from './listTests'; -import { Entry, StepBeginParams, StepEndParams, TestBeginParams, TestEndParams } from './oopReporter'; -import type { TestError } from './reporter'; +import type { TestError, Entry, StepBeginParams, StepEndParams, TestBeginParams, TestEndParams } from './oopReporter'; import { ReporterServer } from './reporterServer'; import { ReusedBrowser } from './reusedBrowser'; import { findNode, spawnAsync } from './utils'; @@ -152,7 +151,7 @@ export class PlaywrightTest { private async _test(config: TestConfig, locations: string[], args: string[], listener: TestListener, mode: 'list' | 'run', token: vscodeTypes.CancellationToken): Promise { // Playwright will restart itself as child process in the ESM mode and won't inherit the 3/4 pipes. // Always use ws transport to mitigate it. - const reporterServer = new ReporterServer(); + const reporterServer = new ReporterServer(this._vscode); const node = await findNode(); if (token?.isCancellationRequested) return; @@ -230,7 +229,7 @@ export class PlaywrightTest { this._log(`${escapeRegex(path.relative(config.workspaceFolder, configFolder))}> debug -c ${configFile}${relativeLocations.length ? ' ' + relativeLocations.join(' ') : ''}`); } - const reporterServer = new ReporterServer(); + const reporterServer = new ReporterServer(this._vscode); await this._reusedBrowser.willRunTests(config, true); try { await vscode.debug.startDebugging(undefined, { diff --git a/src/reporterServer.ts b/src/reporterServer.ts index 88b72cc3f..5e046677f 100644 --- a/src/reporterServer.ts +++ b/src/reporterServer.ts @@ -20,13 +20,16 @@ import { TestListener } from './playwrightTest'; import { ConnectionTransport } from './transport'; import { createGuid } from './utils'; import * as vscodeTypes from './vscodeTypes'; +import type { Location, TestError, Entry, StepBeginParams, StepEndParams, TestBeginParams, TestEndParams } from './oopReporter'; export class ReporterServer { private _clientSocketPromise: Promise; private _clientSocketCallback!: (socket: WebSocket) => void; private _wsServer: WebSocketServer | undefined; + private _vscode: vscodeTypes.VSCode; - constructor() { + constructor(vscode: vscodeTypes.VSCode) { + this._vscode = vscode; this._clientSocketPromise = new Promise(f => this._clientSocketCallback = f); } @@ -86,12 +89,16 @@ export class ReporterServer { if (token.isCancellationRequested && message.method !== 'onEnd') return; switch (message.method) { - case 'onBegin': listener.onBegin?.(message.params); break; - case 'onTestBegin': listener.onTestBegin?.(message.params); break; - case 'onTestEnd': listener.onTestEnd?.(message.params); break; - case 'onStepBegin': listener.onStepBegin?.(message.params); break; - case 'onStepEnd': listener.onStepEnd?.(message.params); break; - case 'onError': listener.onError?.(message.params); break; + case 'onBegin': { + (message.params as { projects: Entry[] }).projects.forEach((e: Entry) => patchLocation(this._vscode, e)); + listener.onBegin?.(message.params); + break; + } + case 'onTestBegin': listener.onTestBegin?.(patchLocation(this._vscode, message.params as TestBeginParams)); break; + case 'onTestEnd': listener.onTestEnd?.(patchLocation(this._vscode, message.params as TestEndParams)); break; + case 'onStepBegin': listener.onStepBegin?.(patchLocation(this._vscode, message.params as StepBeginParams)); break; + case 'onStepEnd': listener.onStepEnd?.(patchLocation(this._vscode, message.params as StepEndParams)); break; + case 'onError': listener.onError?.(patchLocation(this._vscode, message.params as { error: TestError })); break; case 'onEnd': { listener.onEnd?.(); transport.close(); @@ -136,5 +143,20 @@ export class ReporterServer { }); return transport; } +} +function patchLocation(vscode: vscodeTypes.VSCode, object: T): T { + // Normalize all the location.file values using the Uri.file().fsPath normalization. + // vscode will normalize Windows drive letter, etc. + if (object.location) + object.location.file = vscode.Uri.file(object.location.file).fsPath; + if (object.error?.location) + object.error.location.file = vscode.Uri.file(object.error.location.file).fsPath; + if (object.errors) { + object.errors.forEach(e => { + if (e.location) + e.location.file = vscode.Uri.file(e.location.file).fsPath; + }); + } + return object; } diff --git a/src/testModel.ts b/src/testModel.ts index 291c4a790..732875b0e 100644 --- a/src/testModel.ts +++ b/src/testModel.ts @@ -14,13 +14,12 @@ * limitations under the License. */ -import { Entry } from './oopReporter'; +import { Entry, TestError } from './oopReporter'; import { PlaywrightTest, TestConfig, TestListener } from './playwrightTest'; import { WorkspaceChange } from './workspaceObserver'; import * as vscodeTypes from './vscodeTypes'; import { resolveSourceMap } from './utils'; import { ProjectConfigWithFiles } from './listTests'; -import { TestError } from './reporter'; /** * This class builds the Playwright Test model in Playwright terms. diff --git a/src/testTree.ts b/src/testTree.ts index 00c14b34e..9622ca2e0 100644 --- a/src/testTree.ts +++ b/src/testTree.ts @@ -16,8 +16,7 @@ import path from 'path'; import { MultiMap } from './multimap'; -import { Entry, EntryType } from './oopReporter'; -import { Location } from './reporter'; +import type { Location, Entry, EntryType } from './oopReporter'; import { TestModel, TestProject } from './testModel'; import { createGuid } from './utils'; import * as vscodeTypes from './vscodeTypes';