feat: add missing translations

This commit is contained in:
sanish-bruno
2025-05-09 17:56:32 +05:30
parent fb7d247fa7
commit 3dfb158382
6 changed files with 211 additions and 10 deletions

View File

@@ -20,6 +20,11 @@ const replacements = {
'pm\\.response\\.text\\(\\)': 'JSON.stringify(res.getBody())',
'pm\\.expect\\.fail\\(': 'expect.fail(',
'pm\\.response\\.responseTime': 'res.getResponseTime()',
'pm\\.globals\\.set\\(': 'bru.setGlobalEnvVar(',
'pm\\.globals\\.get\\(': 'bru.getGlobalEnvVar(',
'pm\\.response\\.headers\\.get\\(': 'res.getHeader(',
'pm\\.response\\.to\\.have\\.body\\(': 'expect(res.getBody()).to.equal(',
'pm\\.response\\.to\\.have\\.header\\(': 'expect(Object.keys(res.getHeaders())).to.include(',
'pm\\.environment\\.name': 'bru.getEnvName()',
'pm\\.response\\.status': 'res.statusText',
'pm\\.response\\.headers': 'res.getHeaders()',

View File

@@ -38,6 +38,10 @@ function getMemberExpressionString(node) {
// Simple 1:1 translations for straightforward replacements
const simpleTranslations = {
// Global Variables
'pm.globals.get': 'bru.getGlobalEnvVar',
'pm.globals.set': 'bru.setGlobalEnvVar',
// Environment variables
'pm.environment.get': 'bru.getEnvVar',
'pm.environment.set': 'bru.setEnvVar',
@@ -124,7 +128,12 @@ const complexTransformations = [
return j.callExpression(j.identifier('JSON.stringify'), [j.identifier('res.getBody()')]);
}
},
{
pattern: 'pm.response.headers.get',
transform: (path, j) => {
return j.callExpression(j.identifier('res.getHeader'), path.parent.value.arguments);
}
},
// Handle pm.response.to.have.status
{
pattern: 'pm.response.to.have.status',
@@ -191,6 +200,24 @@ const complexTransformations = [
}
},
// handle pm.response.to.have.body to expect(res.getBody()).to.equal(arg)
{
pattern: 'pm.response.to.have.body',
transform: (path, j) => {
const callExpr = path.parent.value;
const args = callExpr.arguments;
return j.callExpression(
j.memberExpression(
j.callExpression(j.identifier('expect'), [j.identifier('res.getBody()')]),
j.identifier('to.equal')
),
args
);
}
},
// Handle pm.execution.setNextRequest(null)
{
@@ -225,7 +252,7 @@ complexTransformations.forEach(transform => {
complexTransformationsMap[transform.pattern] = transform;
});
const varInitsToReplace = new Set(['pm', 'postman', 'pm.request','pm.response', 'pm.test', 'pm.expect', 'pm.environment', 'pm.variables', 'pm.collectionVariables', 'pm.execution']);
const varInitsToReplace = new Set(['pm', 'postman', 'pm.request','pm.response', 'pm.test', 'pm.expect', 'pm.environment', 'pm.variables', 'pm.collectionVariables', 'pm.execution', 'pm.globals']);
/**
* Process all transformations (both simple and complex) in the AST in a single pass

View File

@@ -411,8 +411,85 @@ describe('Combined API Features Translation', () => {
`;
const translatedCode = translateCode(code);
expect(translatedCode).toBe(`
const globals = pm.globals;
const key = globals.get("key");
const key = bru.getGlobalEnvVar("key");
`);
})
it('should handle pm.response.to.have.body integrated with other assertions', () => {
const code = `
pm.test("Response validation", function() {
pm.response.to.have.status(200);
pm.response.to.have.body({"success": true});
pm.response.to.have.header("Content-Type", "application/json");
});
`;
const translatedCode = translateCode(code);
const expectedOutput = `
test("Response validation", function() {
expect(res.getStatus()).to.equal(200);
expect(res.getBody()).to.equal({"success": true});
expect(res.getHeaders()).to.have.property("Content-Type".toLowerCase(), "application/json");
});
`;
expect(translatedCode).toBe(expectedOutput);
});
it('should handle pm.response.to.have.body with dynamic content', () => {
const code = `
const expectedResponse = {
id: pm.environment.get("userId"),
token: pm.variables.get("authToken"),
timestamp: new Date().getTime()
};
pm.test("Dynamic response validation", function() {
pm.response.to.have.body(expectedResponse);
});
`;
const translatedCode = translateCode(code);
const expectedOutput = `
const expectedResponse = {
id: bru.getEnvVar("userId"),
token: bru.getVar("authToken"),
timestamp: new Date().getTime()
};
test("Dynamic response validation", function() {
expect(res.getBody()).to.equal(expectedResponse);
});
`
expect(translatedCode).toBe(expectedOutput);
});
it('should handle pm.response.to.have.body in control structures', () => {
const code = `
const jsonData = pm.response.json();
if (jsonData.status === "success") {
pm.response.to.have.body({
status: "success",
data: jsonData.data
});
} else {
pm.expect(jsonData.error).to.exist;
}
`;
const translatedCode = translateCode(code);
const expectedOutput = `
const jsonData = res.getBody();
if (jsonData.status === "success") {
expect(res.getBody()).to.equal({
status: "success",
data: jsonData.data
});
} else {
expect(jsonData.error).to.exist;
}
`;
expect(translatedCode).toBe(expectedOutput);
});
});

View File

@@ -27,7 +27,7 @@ describe('Legacy Tests[] Syntax Translation', () => {
const translatedCode = translateCode(code);
expect(translatedCode).toBe(`
test("Content-Type is application/json", function() {
expect(Boolean(res.getHeaders().get("Content-Type") === "application/json")).to.be.true;
expect(Boolean(res.getHeader("Content-Type") === "application/json")).to.be.true;
});`);
});
@@ -273,7 +273,7 @@ describe('Legacy Tests[] Syntax Translation', () => {
expect(translatedCode).toContain('test("Has content-type header", function() {');
expect(translatedCode).toContain('expect(Boolean(res.getHeaders().has("Content-Type"))).to.be.true;');
expect(translatedCode).toContain('test("Content-Type is JSON", function() {');
expect(translatedCode).toContain('expect(Boolean(res.getHeaders().get("Content-Type").includes("application/json"))).to.be.true;');
expect(translatedCode).toContain('expect(Boolean(res.getHeader("Content-Type").includes("application/json"))).to.be.true;');
expect(translatedCode).toContain('const expectedItems = parseInt(bru.getEnvVar("expectedItemCount"));');
expect(translatedCode).toContain('test("Has correct number of items", function() {');
expect(translatedCode).toContain('expect(Boolean(response.items.length === expectedItems)).to.be.true;');

View File

@@ -32,6 +32,12 @@ describe('Response Translation', () => {
expect(translatedCode).toBe('console.log("Status text:", res.statusText);');
});
it('should translate pm.response.headers', () => {
const code = 'console.log("Headers:", pm.response.headers);';
const translatedCode = translateCode(code);
expect(translatedCode).toBe('console.log("Headers:", res.getHeaders());');
});
// Complex response transformations
it('should transform pm.response.to.have.status', () => {
const code = 'pm.response.to.have.status(201);';
@@ -178,6 +184,17 @@ describe('Response Translation', () => {
`);
});
it('should translate response.headers', () => {
const code = `
const resp = pm.response;
const headers = resp.headers;
`;
const translatedCode = translateCode(code);
expect(translatedCode).toBe(`
const headers = res.getHeaders();
`);
});
it('should translate pm.response.statusText', () => {
const code = `
const resp = pm.response;
@@ -296,8 +313,8 @@ describe('Response Translation', () => {
const translatedCode = translateCode(code);
// Check how header access is translated
expect(translatedCode).toContain('const contentType = res.getHeaders().get(\'Content-Type\');');
expect(translatedCode).toContain('const contentLength = res.getHeaders().get(\'Content-Length\');');
expect(translatedCode).toContain('const contentType = res.getHeader(\'Content-Type\');');
expect(translatedCode).toContain('const contentLength = res.getHeader(\'Content-Length\');');
expect(translatedCode).toContain('console.log("contentType", contentType);');
expect(translatedCode).toContain('console.log("contentLength", contentLength);');
expect(translatedCode).not.toContain('pm.test')
@@ -340,7 +357,7 @@ describe('Response Translation', () => {
const translatedCode = translateCode(code);
expect(translatedCode).toContain('if (res.getStatus() >= 200 && res.getStatus() < 300) {');
expect(translatedCode).toContain('if (res.getHeaders().get(\'Content-Type\').includes(\'application/json\')) {');
expect(translatedCode).toContain('if (res.getHeader(\'Content-Type\').includes(\'application/json\')) {');
expect(translatedCode).toContain('const data = res.getBody();');
expect(translatedCode).toContain('bru.setEnvVar("authToken", data.token);');
expect(translatedCode).toContain('} else if (res.getStatus() === 404) {');
@@ -486,4 +503,54 @@ describe('Response Translation', () => {
expect(translatedCode).toContain('checkHeaderPresent("Authorization");');
expect(translatedCode).toContain('validateHeader("Content-Type", "application/json");');
});
it('should transform pm.response.to.have.body with string literal', () => {
const code = 'pm.response.to.have.body("Expected response body");';
const translatedCode = translateCode(code);
expect(translatedCode).toBe('expect(res.getBody()).to.equal("Expected response body");');
});
it('should transform pm.response.to.have.body with variable parameter', () => {
const code = `
const expectedBody = {"status": "success", "data": [1, 2, 3]};
pm.response.to.have.body(expectedBody);
`;
const translatedCode = translateCode(code);
expect(translatedCode).toContain('const expectedBody = {"status": "success", "data": [1, 2, 3]};');
expect(translatedCode).toContain('expect(res.getBody()).to.equal(expectedBody);');
});
it('should transform pm.response.to.have.body with JSON object', () => {
const code = `pm.response.to.have.body({"status": "success", "message": "Operation completed"});`;
const translatedCode = translateCode(code);
expect(translatedCode).toBe('expect(res.getBody()).to.equal({"status": "success", "message": "Operation completed"});');
});
it('should transform pm.response.to.have.body inside test function', () => {
const code = `
pm.test("Response body validation", function() {
const expectedResponse = {"result": true};
pm.response.to.have.body(expectedResponse);
});
`;
const translatedCode = translateCode(code);
const expectedOutput = `
test("Response body validation", function() {
const expectedResponse = {"result": true};
expect(res.getBody()).to.equal(expectedResponse);
});
`
expect(translatedCode).toBe(expectedOutput);
});
it('should transform pm.response.to.have.body with response alias', () => {
const code = `
const resp = pm.response;
resp.to.have.body({"status": "ok"});
`;
const translatedCode = translateCode(code);
expect(translatedCode).toBe(`
expect(res.getBody()).to.equal({"status": "ok"});
`);
});
});

View File

@@ -45,6 +45,18 @@ describe('Variables Translation', () => {
expect(translatedCode).toBe('bru.deleteVar("tempVar");');
});
it('should handle pm.globals.get', () => {
const code = 'pm.globals.get("test");';
const translatedCode = translateCode(code);
expect(translatedCode).toBe('bru.getGlobalEnvVar("test");');
});
it('should handle pm.globals.set', () => {
const code = 'pm.globals.set("test", "value");';
const translatedCode = translateCode(code);
expect(translatedCode).toBe('bru.setGlobalEnvVar("test", "value");');
});
// Alias tests for variables
it('should handle variables aliases', () => {
const code = `
@@ -79,6 +91,19 @@ describe('Variables Translation', () => {
`);
});
it('should handle pm.globals aliases', () => {
const code = `
const globals = pm.globals;
const get = globals.get("test");
const set = globals.set("test", "value");
`;
const translatedCode = translateCode(code);
expect(translatedCode).toBe(`
const get = bru.getGlobalEnvVar("test");
const set = bru.setGlobalEnvVar("test", "value");
`);
})
// Combined tests
it('should handle conditional expressions with variable calls', () => {
const code = 'const userStatus = pm.variables.has("userId") ? "logged-in" : "guest";';
@@ -124,5 +149,5 @@ describe('Variables Translation', () => {
const code = 'pm.collectionVariables.set("fullPath", pm.environment.get("baseUrl") + pm.variables.get("endpoint"));';
const translatedCode = translateCode(code);
expect(translatedCode).toBe('bru.setVar("fullPath", bru.getEnvVar("baseUrl") + bru.getVar("endpoint"));');
});
});
});