Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Test Utils] [Recorder] Migrate to esm #28667

Merged
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
e503d82
unreleased
HarshaNalluru Sep 22, 2023
b34f67c
Merge branch 'main' of https://github.com/harshanalluru/azure-sdk-for-js
HarshaNalluru Sep 26, 2023
505f1b3
empty
HarshaNalluru Sep 26, 2023
2fe1ffb
Merge branch 'Azure:main' into main
HarshaNalluru Oct 23, 2023
5619dcf
Merge branch 'main' of https://github.com/harshanalluru/azure-sdk-for-js
HarshaNalluru Oct 31, 2023
973988d
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-js
HarshaNalluru Nov 23, 2023
5c3718b
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-js
HarshaNalluru Dec 7, 2023
1621db1
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-js
HarshaNalluru Dec 19, 2023
b203af9
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-js
HarshaNalluru Jan 23, 2024
31bf8d1
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-js
HarshaNalluru Feb 6, 2024
ef9c226
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-js
HarshaNalluru Feb 9, 2024
4c14b2a
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-js
HarshaNalluru Feb 13, 2024
693683c
[test-recorder] Support test context from vitest (#28350)
jeremymeng Jan 31, 2024
0a0d56b
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-js
HarshaNalluru Feb 22, 2024
cbd8105
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-js
HarshaNalluru Feb 23, 2024
4d055b5
first draft - before fixing test build failures
HarshaNalluru Feb 26, 2024
ffb931c
Merge branch 'recorder/vitest-context' of https://github.com/jeremyme…
HarshaNalluru Feb 26, 2024
cdff879
fixing tests halfway
HarshaNalluru Feb 26, 2024
0893aba
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-js into…
HarshaNalluru Feb 26, 2024
66a8c03
lock file
HarshaNalluru Feb 26, 2024
e45d1a9
lock file
HarshaNalluru Feb 26, 2024
59e6787
final fixes to tests
HarshaNalluru Feb 27, 2024
bcdebcd
expose more types
HarshaNalluru Feb 27, 2024
4bfc467
Merge branch 'recorder/vitest-context' of https://github.com/jeremyme…
HarshaNalluru Feb 29, 2024
c8ba527
node tests work fine, browser tests... figuring out
HarshaNalluru Feb 29, 2024
2348844
checkpoint
HarshaNalluru Feb 29, 2024
ad16125
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-js into…
HarshaNalluru Feb 29, 2024
f12bcc7
dummy commit
HarshaNalluru Feb 29, 2024
e9e432a
dummy commit
HarshaNalluru Feb 29, 2024
dc6813d
format and lock file
HarshaNalluru Feb 29, 2024
0d586fb
typedoc fixes
HarshaNalluru Mar 1, 2024
babc232
dummy commit
HarshaNalluru Mar 1, 2024
c539c73
pre-hook
HarshaNalluru Mar 1, 2024
fa143ff
disable web security
HarshaNalluru Mar 5, 2024
71e9f64
checkpoint - both browser and node tests working fine
HarshaNalluru Mar 9, 2024
d9c5736
format
HarshaNalluru Mar 9, 2024
1164e32
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-js into…
HarshaNalluru Mar 9, 2024
415c91f
node and browser work fine - checkpoint - recorder
HarshaNalluru Mar 9, 2024
2a8935b
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-js into…
HarshaNalluru Mar 11, 2024
4178384
tsconfig
HarshaNalluru Mar 11, 2024
0769e0f
lock file
HarshaNalluru Mar 11, 2024
2b28254
app-config changes
HarshaNalluru Mar 14, 2024
aaeafa7
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-js into…
HarshaNalluru Mar 14, 2024
8d2e0a0
fix conflict
HarshaNalluru Mar 14, 2024
cf6e783
4.0.0 recorder 👶
HarshaNalluru Mar 14, 2024
c72ed28
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-js into…
HarshaNalluru Mar 19, 2024
1d435c4
lock file
HarshaNalluru Mar 19, 2024
8ef9862
switch template
HarshaNalluru Mar 19, 2024
923c25e
revert app-config
HarshaNalluru Mar 19, 2024
ec64e7e
revert app-config
HarshaNalluru Mar 19, 2024
9bb7b36
lock file
HarshaNalluru Mar 19, 2024
ad314b2
template update
HarshaNalluru Mar 19, 2024
7e83492
update test credential package
HarshaNalluru Mar 21, 2024
ee3524f
changelog
HarshaNalluru Mar 21, 2024
0e1c678
make "@azure-tools/test-credential" version consistent
HarshaNalluru Mar 21, 2024
7746859
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-js into…
HarshaNalluru Mar 21, 2024
6cf7fc9
Merge branch 'harshan/publish-test-credential-current' of https://git…
HarshaNalluru Mar 21, 2024
48febd3
lock file
HarshaNalluru Mar 21, 2024
c51536c
lock file
HarshaNalluru Mar 21, 2024
cb9a7d9
lock file and clean up
HarshaNalluru Mar 21, 2024
9d805e1
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-js into…
HarshaNalluru Mar 21, 2024
09632d6
revert non recorder changes
HarshaNalluru Mar 21, 2024
4407b05
more reversions
HarshaNalluru Mar 21, 2024
c95c077
lock file
HarshaNalluru Mar 21, 2024
e0a9360
revert template
HarshaNalluru Mar 21, 2024
7dc8322
correct reversion for template
HarshaNalluru Mar 21, 2024
6e25e4d
clean up
HarshaNalluru Mar 21, 2024
f15502b
changelog
HarshaNalluru Mar 21, 2024
9c6f0c6
remove console.logs and address comments
HarshaNalluru Mar 21, 2024
1d2bc19
format
HarshaNalluru Mar 21, 2024
e92441d
fix tests
HarshaNalluru Mar 21, 2024
a3251b7
address feedback
HarshaNalluru Mar 29, 2024
6456ff7
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-js into…
HarshaNalluru Mar 29, 2024
7ab816e
lock file
HarshaNalluru Mar 29, 2024
303f2f2
Apply suggestions from code review
mpodwysocki Mar 29, 2024
6b50763
Update sdk/test-utils/recorder/package.json
mpodwysocki Mar 29, 2024
c4b905c
lock file
HarshaNalluru Mar 31, 2024
a5c82ed
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-js into…
HarshaNalluru Mar 31, 2024
383f331
lock file
HarshaNalluru Mar 31, 2024
ee8228b
rush update --full
HarshaNalluru Mar 31, 2024
9c4ae23
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-js into…
HarshaNalluru Apr 1, 2024
d0582e8
lock file
HarshaNalluru Apr 1, 2024
9b35527
rush update --full
HarshaNalluru Apr 1, 2024
cc381c7
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-js into…
HarshaNalluru Apr 1, 2024
a4a73c4
lock file
HarshaNalluru Apr 1, 2024
871b186
remove @types/express
HarshaNalluru Apr 1, 2024
161b4d6
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-js into…
HarshaNalluru Apr 1, 2024
7b1a01c
lock file with rush update --full
HarshaNalluru Apr 1, 2024
61db6e9
fix glob pattern for windows
HarshaNalluru Apr 1, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion sdk/test-utils/recorder/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,13 @@
"homepage": "https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/test-utils/recorder/",
"sideEffects": false,
"dependencies": {
"@azure/core-client": "^1.0.0",
"@azure/core-rest-pipeline": "^1.13.0",
"@azure/core-auth": "^1.3.2",
"@azure/core-util": "^1.6.1",
"@azure/logger": "^1.0.0"
},
"devDependencies": {
"@azure/core-client": "^1.0.0",
"@azure/dev-tool": "^1.0.0",
"@azure/eslint-plugin-azure-sdk": "^3.0.0",
"@types/express": "^4.16.0",
Expand Down
1 change: 1 addition & 0 deletions sdk/test-utils/recorder/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ export {
export { env } from "./utils/env.js";
export { delay } from "./utils/delay.js";
export { CustomMatcherOptions } from "./matcher.js";
export { TestInfo, MochaTest, VitestTestContext } from "./testInfo.js";
66 changes: 54 additions & 12 deletions sdk/test-utils/recorder/src/recorder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ import {
RecorderStartOptions,
RecordingStateManager,
} from "./utils/utils.js";
import { Test } from "mocha";
import { assetsJsonPath, sessionFilePath } from "./utils/sessionFilePath.js";
import { assetsJsonPath, sessionFilePath, TestContext } from "./utils/sessionFilePath.js";
import { SanitizerOptions } from "./utils/utils.js";
import { paths } from "./utils/paths.js";
import { addSanitizers, transformsInfo } from "./sanitizer.js";
Expand All @@ -35,6 +34,45 @@ import { isBrowser, isNode } from "@azure/core-util";
import { env } from "./utils/env.js";
import { decodeBase64 } from "./utils/encoding.js";
import { AdditionalPolicyConfig } from "@azure/core-client";
import { isMochaTest, isVitestTestContext, TestInfo, VitestSuite } from "./testInfo.js";

/**
* Caculates session file path and JSON assets path from test context
*
* @internal
*/
export function calculatePaths(testContext: TestInfo): TestContext {
if (isMochaTest(testContext)) {
if (!testContext.parent) {
throw new RecorderError(
`The parent of test '${testContext.title}' is undefined, so a file path for its recording could not be generated. Please place the test inside a describe block.`,
);
}
return {
suiteTitle: testContext.parent.fullTitle(),
testTitle: testContext.title,
};
} else if (isVitestTestContext(testContext)) {
if (!testContext.task.name || !testContext.task.suite.name) {
throw new RecorderError(
`Unable to determine the recording file path. Unexpected empty Vitest context`,
);
}
const suites: string[] = [];
let p: VitestSuite | undefined = testContext.task.suite;
while (p?.name) {
suites.push(p.name);
p = p.suite;
}

return {
suiteTitle: suites.reverse().join("_"),
testTitle: testContext.task.name,
};
} else {
throw new RecorderError(`Unrecognized test info: ${testContext}`);
}
}

/**
* This client manages the recorder life cycle and interacts with the proxy-tool to do the recording,
Expand All @@ -54,19 +92,23 @@ export class Recorder {
private variables: Record<string, string>;
private matcherSet = false;

constructor(private testContext?: Test | undefined) {
constructor(private testContext?: TestInfo) {
if (!this.testContext) {
throw new Error(
"Unable to determine the recording file path, testContext provided is not defined.",
);
}

logger.info(`[Recorder#constructor] Creating a recorder instance in ${getTestMode()} mode`);
if (isRecordMode() || isPlaybackMode()) {
if (this.testContext) {
this.sessionFile = sessionFilePath(this.testContext);
this.assetsJson = assetsJsonPath();
const context = calculatePaths(this.testContext);

this.sessionFile = sessionFilePath(context);
this.assetsJson = assetsJsonPath();

if (this.testContext) {
logger.info(`[Recorder#constructor] Using a session file located at ${this.sessionFile}`);
this.httpClient = createDefaultHttpClient();
} else {
throw new Error(
"Unable to determine the recording file path, testContext provided is not defined.",
);
}
}
this.variables = {};
Expand Down Expand Up @@ -431,7 +473,7 @@ export class Recorder {
}

if (ensureExistence(this.httpClient, "this.httpClient")) {
return await transformsInfo(this.httpClient, Recorder.url, this.recordingId!);
return transformsInfo(this.httpClient, Recorder.url, this.recordingId!);
}

throw new RecorderError("Expected httpClient to be defined");
Expand Down Expand Up @@ -463,7 +505,7 @@ export class Recorder {
return options;
}

private handleTestProxyErrors(response: PipelineResponse) {
private handleTestProxyErrors(response: PipelineResponse): void {
if (response.headers.get("x-request-mismatch") === "true") {
const errorMessage = decodeBase64(response.headers.get("x-request-mismatch-error") ?? "");
logger.error(
Expand Down
91 changes: 91 additions & 0 deletions sdk/test-utils/recorder/src/testInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

/**
* Represents a Test.
*/
export type TestInfo = MochaTest | VitestTestContext;

/**
* Represents a Mocha Test.
*/
export interface MochaTest {
/**
* The title of the test.
*/
title: string;
/**
* The parent of the Mocha Test Suite.
*/
parent?: MochaTestSuite;
}

/**
* Represents a Mocha Test Suite.
*/
export interface MochaTestSuite {
fullTitle(): string;
}

/**
* Represents a Vitest Test Context
*/
export interface VitestTestContext {
/**
* The Vitest Context Task.
*/
task: VitestTask;
}

export interface VitestTaskBase {
name: string;
suite?: VitestSuite;
}

/**
* Represents a Vitest Test Context Task
*/
export interface VitestTask extends VitestTaskBase {
/**
* The Vitest Context Task Name.
*/
name: string;
/**
* The Vitest Context Task Suite.
*/
suite: VitestSuite;
}

/**
* Represents a Vitest Test Suite.
*/
export interface VitestSuite extends VitestTaskBase {
/**
* The Vitest Context Task Suite Name.
*/
name: string;
}

/**
* Determines whether the given test is a Mocha Test.
* @param test - The test to check.
* @returns true if the given test is a Mocha Test.
*/
export function isMochaTest(test: unknown): test is MochaTest {
return typeof test === "object" && test != null && "title" in test;
}

/**
* Determines whether the given test is a Vitest Test.
* @param test - The test to check.
* @returns true if the given test is a Vitest Test.
*/
export function isVitestTestContext(test: unknown): test is VitestTestContext {
return (
typeof test == "function" &&
"task" in test &&
typeof test.task === "object" &&
test.task != null &&
"name" in test.task
);
}
20 changes: 9 additions & 11 deletions sdk/test-utils/recorder/src/utils/sessionFilePath.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@
import { isNode } from "@azure/core-util";
import { generateTestRecordingFilePath } from "./filePathGenerator.js";
import { relativeRecordingsPath } from "./relativePathCalculator.js";
import { RecorderError } from "./utils.js";

export function sessionFilePath(testContext: Mocha.Test): string {
export interface TestContext {
suiteTitle: string; // describe(suiteTitle, () => {})
testTitle: string; // it(testTitle, () => {})
}

export function sessionFilePath(testContext: TestContext): string {
// sdk/service/project/recordings/{node|browsers}/<describe-block-title>/recording_<test-title>.json
return `${relativeRecordingsPath()}/${recordingFilePath(testContext)}`;
}
Expand All @@ -16,17 +20,11 @@ export function sessionFilePath(testContext: Mocha.Test): string {
*
* `{node|browsers}/<describe-block-title>/recording_<test-title>.json`
*/
export function recordingFilePath(testContext: Mocha.Test): string {
if (!testContext.parent) {
throw new RecorderError(
`Test ${testContext.title} is not inside a describe block, so a file path for its recording could not be generated. Please place the test inside a describe block.`,
);
}

export function recordingFilePath(testContext: TestContext): string {
return generateTestRecordingFilePath(
isNode ? "node" : "browsers",
testContext.parent.fullTitle(),
testContext.title,
testContext.suiteTitle,
testContext.testTitle,
);
}

Expand Down
6 changes: 3 additions & 3 deletions sdk/test-utils/recorder/test/errors.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { expect } from "chai";
import { Recorder } from "../src/recorder.js";
import { createHttpHeaders, createPipelineRequest } from "@azure/core-rest-pipeline";
import { encodeBase64 } from "../src/utils/encoding.js";
import { describe, it, beforeEach } from "vitest";
import { describe, it, beforeEach, TaskContext } from "vitest";

describe("State Manager", function () {
it("throws error if started twice", function () {
Expand Down Expand Up @@ -39,8 +39,8 @@ describe("State Manager", function () {

describe("handleTestProxyErrors", function () {
let recorder: Recorder;
beforeEach(function (this: Mocha.Context) {
recorder = new Recorder(this.currentTest);
beforeEach(function (this: TaskContext) {
recorder = new Recorder(this.task.context);
});

it("x-request-mismatch header", function () {
Expand Down
62 changes: 62 additions & 0 deletions sdk/test-utils/recorder/test/recorder.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import { expect } from "chai";
HarshaNalluru marked this conversation as resolved.
Show resolved Hide resolved

import { calculatePaths } from "../src/recorder.js";

describe("Recorder file paths", () => {
it("calculates paths for a Mocha test", () => {
const mochaTest = {
title: "mocha test title",
parent: {
fullTitle: () => "mocha suite title",
},
};
const context = calculatePaths(mochaTest);

expect(context).to.eql({
suiteTitle: "mocha suite title",
testTitle: "mocha test title",
});
});

it("calculates paths for a vitest test", () => {
const vitestTest = () => {
/* no-op */
};
(vitestTest as any).task = {
name: "vitest test title",
suite: {
name: "vitest suite title",
},
};

const context = calculatePaths(vitestTest as any);
expect(context).to.eql({
suiteTitle: "vitest suite title",
testTitle: "vitest test title",
});
});

it("calculates paths for a vitest test with nested suites", () => {
const vitestTest = () => {
/* no-op */
};
(vitestTest as any).task = {
name: "vitest test title",
suite: {
name: "vitest suite title",
suite: {
name: "toplevel suite",
},
},
};

const context = calculatePaths(vitestTest as any);
expect(context).to.eql({
suiteTitle: "toplevel suite_vitest suite title",
testTitle: "vitest test title",
});
});
});
2 changes: 1 addition & 1 deletion sdk/test-utils/recorder/test/sanitizers.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { env, isPlaybackMode, Recorder } from "../src/index.js";
import { TestMode } from "../src/utils/utils.js";
import { TEST_SERVER_URL, makeRequestAndVerifyResponse, setTestMode } from "./utils/utils.js";
import { randomUUID } from "@azure/core-util";
import { describe, it, beforeEach, afterEach, beforeAll, Vitest, TaskContext } from "vitest";
import { describe, it, beforeEach, afterEach, beforeAll, TaskContext } from "vitest";

// These tests require the following to be running in parallel
// - utils/server.ts (to serve requests to act as a service)
Expand Down
10 changes: 5 additions & 5 deletions sdk/test-utils/recorder/test/testProxyClient.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { env, Recorder } from "../src/index.js";
import { createRecordingRequest } from "../src/utils/createRecordingRequest.js";
import { paths } from "../src/utils/paths.js";
import { getTestMode, isLiveMode, isRecordMode, RecorderError } from "../src/utils/utils.js";
import { describe, it, beforeEach, afterEach, } from "vitest";
import { describe, it, beforeEach, afterEach, TaskContext, } from "vitest";

const testRedirectedRequest = (
client: Recorder,
Expand All @@ -27,11 +27,11 @@ const testRedirectedRequest = (
describe("TestProxyClient functions", () => {
let client: Recorder;
let clientHttpClient: HttpClient;
let testContext: Mocha.Test | undefined;
beforeEach(function (this: Mocha.Context) {
client = new Recorder(this.currentTest);
let testContext: TaskContext | undefined;
beforeEach(async function (this: TaskContext) {
testContext = this.task.context;
client = new Recorder(testContext);
clientHttpClient = client["httpClient"] as HttpClient;
testContext = this.currentTest;
});

afterEach(() => {
Expand Down
6 changes: 3 additions & 3 deletions sdk/test-utils/recorder/test/testProxyTests.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { expect } from "chai";
import { CustomMatcherOptions, isPlaybackMode, Recorder } from "../src/index.js";
import { isLiveMode, TestMode } from "../src/utils/utils.js";
import { TEST_SERVER_URL, makeRequestAndVerifyResponse } from "./utils/utils.js";
import { describe, it, beforeEach } from "vitest";
import { describe, it, beforeEach, TaskContext } from "vitest";

// These tests require the following to be running in parallel
// - utils/server.ts (to serve requests to act as a service)
Expand All @@ -18,8 +18,8 @@ import { describe, it, beforeEach } from "vitest";
let recorder: Recorder;
let client: ServiceClient;

beforeEach(async function (this: Mocha.Context) {
recorder = new Recorder(this.currentTest);
beforeEach(async function (this: TaskContext) {
recorder = new Recorder(this.task.context);
client = new ServiceClient(recorder.configureClientOptions({ baseUri: TEST_SERVER_URL }));
});

Expand Down