mirror of
https://github.com/usebruno/bruno.git
synced 2026-07-02 17:08:32 +00:00
Fix/add missing translations (#4637)
* fix: add missing deps * feat: add missing translations * fix: regex tranasaltion for to.have.headers
This commit is contained in:
15
package-lock.json
generated
15
package-lock.json
generated
@@ -8290,7 +8290,6 @@
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz",
|
||||
"integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/lodash": {
|
||||
@@ -8313,7 +8312,6 @@
|
||||
"version": "12.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz",
|
||||
"integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/linkify-it": "*",
|
||||
@@ -8324,7 +8322,6 @@
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz",
|
||||
"integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/ms": {
|
||||
@@ -13266,7 +13263,6 @@
|
||||
"version": "0.1.13",
|
||||
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
|
||||
"integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
@@ -14733,6 +14729,15 @@
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/flow-parser": {
|
||||
"version": "0.269.1",
|
||||
"resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.269.1.tgz",
|
||||
"integrity": "sha512-2Yr0kqvT7RwaGL192nT78O5AWJeECQjl0NEzBkMsx8OJt63BvNl5yvSIbE4qZ1VDSjEkhbUgaWYdwX354bVNjw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.15.9",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
|
||||
@@ -26469,7 +26474,7 @@
|
||||
"version": "4.9.5",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
|
||||
"integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
|
||||
@@ -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(res.getHeaders()).to.have.property(',
|
||||
'pm\\.environment\\.name': 'bru.getEnvName()',
|
||||
'pm\\.response\\.status': 'res.statusText',
|
||||
'pm\\.response\\.headers': 'res.getHeaders()',
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
@@ -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;');
|
||||
|
||||
@@ -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"});
|
||||
`);
|
||||
});
|
||||
});
|
||||
@@ -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"));');
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user