시나리오 관리 추가
This commit is contained in:
@@ -3,7 +3,6 @@ require.config({paths: {'vs': '/plugins/vs'}});
|
||||
|
||||
class APITester {
|
||||
|
||||
|
||||
constructor() {
|
||||
this.servers = [];
|
||||
this.apiTabTitleTarget = '#apiRequestTabTitle';
|
||||
@@ -16,9 +15,9 @@ class APITester {
|
||||
this.responseEditors = []; //API response body editor
|
||||
this.preRequestEditors = [];
|
||||
this.postRequestEditors = [];
|
||||
window.globals = {};
|
||||
this.globalVariables = window.globals;
|
||||
|
||||
this.variables = {};
|
||||
this.apiClient = new APIClient();
|
||||
}
|
||||
|
||||
renderServers(selectedServer) {
|
||||
@@ -304,7 +303,7 @@ class APITester {
|
||||
|
||||
collectionTemplate(collection, index) {
|
||||
return `
|
||||
<li id="collection_${index}" class="collection" data-index="${index}">
|
||||
<li id="collection_${index}" class="collection api_scenario_item" data-index="${index}">
|
||||
<div class="d-flex justify-content-between">
|
||||
<button class="btn d-inline-flex align-items-center rounded normal"
|
||||
data-bs-toggle="collapse"
|
||||
@@ -326,8 +325,8 @@ class APITester {
|
||||
|
||||
collectionApiTemplate(api, apiIndex, collectionId) {
|
||||
return `
|
||||
<li class="d-flex justify-content-between " data-collection="${collectionId}" data-id="${api.id}" data-index="${apiIndex}">
|
||||
<a href="#" class="d-inline-flex align-items-center rounded open_api_request">${api.name}</a>
|
||||
<li class="d-flex justify-content-between api_request_sortable " draggable="true" data-collection="${collectionId}" data-id="${api.id}" data-index="${apiIndex}" data-node-type="api" data-name="${api.name}">
|
||||
<a href="#" class="d-inline-flex align-items-center rounded open_api_request" data-node-type="api">${api.name}</a>
|
||||
<div class="d-flex justify-content-between">
|
||||
<button class="p-1 reset-button edit_api_request"><i class="fa fa-sharp fa-file-edit"></i></button>
|
||||
<button class="p-1 reset-button delete_api_request"><i class="fa fa-trash-can"></i></button>
|
||||
@@ -339,7 +338,7 @@ class APITester {
|
||||
init(servers) {
|
||||
if (servers) {
|
||||
this.servers = servers;
|
||||
if (this.servers.length === 0){
|
||||
if (this.servers.length === 0) {
|
||||
$('.toast-body').text('서버관리에서 서버를 등록해주세요.');
|
||||
$('.toast').toast('show');
|
||||
}
|
||||
@@ -357,7 +356,7 @@ class APITester {
|
||||
{selector: '.btn_add_variables', action: this.addVariable.bind(this)},
|
||||
{selector: '.btn_remove_variable', action: this.removeVariable.bind(this)},
|
||||
|
||||
{selector: '.send', action: this.sendApiRequest.bind(this)},
|
||||
{selector: '.send', action: this.handleSendAPIRequest.bind(this)},
|
||||
{selector: '.save', action: this.saveAPIRequest.bind(this)},
|
||||
{selector: '.save_collection', action: this.addCollection.bind(this)},
|
||||
{selector: '#cancel-ajax', action: this.cancelAjaxRequest.bind(this)},
|
||||
@@ -379,16 +378,57 @@ class APITester {
|
||||
$(document).on('click', event.selector, event.action);
|
||||
}
|
||||
|
||||
$(document).on('input', '.query_params input', this.handleUIUpdate.bind(this));
|
||||
$(document).on('input', '.query_params input', this.buildPath.bind(this));
|
||||
$(document).on('input', '.query_params input', this.handleUIUpdate.bind(this));
|
||||
$(document).on('input', '.query_params input', this.buildPath.bind(this));
|
||||
$(document).on('change', '.query_params input', this.handleUIUpdate.bind(this));
|
||||
$(document).on('change', '.query_params input', this.buildPath.bind(this));
|
||||
$(document).on('input', '.path', this.parseParam.bind(this));
|
||||
$(document).on('input', '.path', this.parseParam.bind(this));
|
||||
$(document).on('change', '.request_headers input', this.handleUIUpdate.bind(this));
|
||||
$(document).on('change', '.variables input', this.handleUIUpdate.bind(this));
|
||||
$(document).on('change', '.api_request_info select, .api_request_info input', this.handleUIUpdate.bind(this));
|
||||
$(document).on('change', '.api_request_info select', this.handleUpdateServer.bind(this));
|
||||
|
||||
window.addEventListener('resize', this.resizeEditor.bind(this));
|
||||
|
||||
|
||||
}
|
||||
|
||||
resizeEditor() {
|
||||
//FIXME: 창 크기 변경시 자동으로 editor 크기가 조정되지 않아서, 0으로 강제 변경후 다시 layout() 호출
|
||||
|
||||
for (let i = 0; i < this.requestEditors.length; i++) {
|
||||
this.requestEditors[i].layout({
|
||||
width: 0
|
||||
});
|
||||
}
|
||||
for (let i = 0; i < this.responseEditors.length; i++) {
|
||||
this.responseEditors[i].layout({
|
||||
width: 0
|
||||
});
|
||||
}
|
||||
for (let i = 0; i < this.preRequestEditors.length; i++) {
|
||||
this.preRequestEditors[i].layout({
|
||||
width: 0
|
||||
});
|
||||
}
|
||||
for (let i = 0; i < this.postRequestEditors.length; i++) {
|
||||
this.postRequestEditors[i].layout({
|
||||
width: 0
|
||||
});
|
||||
}
|
||||
|
||||
for (let i = 0; i < this.requestEditors.length; i++) {
|
||||
this.requestEditors[i].layout({});
|
||||
}
|
||||
for (let i = 0; i < this.responseEditors.length; i++) {
|
||||
this.responseEditors[i].layout({});
|
||||
}
|
||||
for (let i = 0; i < this.preRequestEditors.length; i++) {
|
||||
this.preRequestEditors[i].layout({});
|
||||
}
|
||||
for (let i = 0; i < this.postRequestEditors.length; i++) {
|
||||
this.postRequestEditors[i].layout({});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -547,7 +587,7 @@ class APITester {
|
||||
this.openTab(model.id);
|
||||
let target = $('#api_request_' + model.id);
|
||||
|
||||
require(['vs/editor/editor.main'], () => {
|
||||
require(['vs/editor/editor.main'], () => {
|
||||
let requestBodyEditor = monaco.editor.create(target.find(".request_body")[0], {
|
||||
value: model.requestBody,
|
||||
language: 'json',
|
||||
@@ -555,15 +595,15 @@ class APITester {
|
||||
automaticLayout: true
|
||||
});
|
||||
me.requestEditors.push(requestBodyEditor);
|
||||
target.find(".request_body")[0].addEventListener('shown.bs.tab', () => {
|
||||
target.find(".request_body")[0].addEventListener('shown.bs.tab', () => {
|
||||
me.requestEditors[index].layout();
|
||||
});
|
||||
|
||||
me.requestEditors[index].onDidChangeModelContent( (e) => {
|
||||
me.requestEditors[index].onDidChangeModelContent((e) => {
|
||||
model.requestBody = requestBodyEditor.getValue();
|
||||
});
|
||||
|
||||
target.find('.request_body_type').on('change', () => {
|
||||
target.find('.request_body_type').on('change', () => {
|
||||
let model = requestBodyEditor.getModel();
|
||||
monaco.editor.setModelLanguage(model, $(this).val());
|
||||
});
|
||||
@@ -583,11 +623,11 @@ class APITester {
|
||||
automaticLayout: true
|
||||
});
|
||||
me.preRequestEditors.push(preRequestEditor);
|
||||
target.find(".pre-request")[0].addEventListener('shown.bs.tab', () => {
|
||||
target.find(".pre-request")[0].addEventListener('shown.bs.tab', () => {
|
||||
me.preRequestEditors[index].layout();
|
||||
});
|
||||
|
||||
me.preRequestEditors[index].onDidChangeModelContent( (e) => {
|
||||
me.preRequestEditors[index].onDidChangeModelContent((e) => {
|
||||
model.preRequestScript = preRequestEditor.getValue();
|
||||
});
|
||||
|
||||
@@ -598,37 +638,32 @@ class APITester {
|
||||
automaticLayout: true
|
||||
});
|
||||
me.postRequestEditors.push(postRequestEditor);
|
||||
target.find(".post-request")[0].addEventListener('shown.bs.tab', () => {
|
||||
target.find(".post-request")[0].addEventListener('shown.bs.tab', () => {
|
||||
me.postRequestEditors[index].layout();
|
||||
});
|
||||
|
||||
me.postRequestEditors[index].onDidChangeModelContent( (e) => {
|
||||
me.postRequestEditors[index].onDidChangeModelContent((e) => {
|
||||
model.postRequestScript = postRequestEditor.getValue();
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
renderResponse(tabIndex) {
|
||||
//console.log('renderResponse: ' + tabIndex);
|
||||
console.log('renderResponse: ' + tabIndex);
|
||||
let model = this.apiRequests[tabIndex];
|
||||
let target = $('#api_request_' + model.id);
|
||||
target.find('.response_headers').empty();
|
||||
target.find(".response_status").empty();
|
||||
|
||||
//console.log(model.responseModel);
|
||||
|
||||
try {
|
||||
const parsedJson = JSON.parse(model.responseModel.body);
|
||||
const formattedJson = JSON.stringify(parsedJson, null, 2);
|
||||
this.responseEditors[tabIndex].setValue(formattedJson);
|
||||
} catch(e) {
|
||||
} catch (e) {
|
||||
this.responseEditors[tabIndex].setValue(model.responseModel.body);
|
||||
}
|
||||
if(model.responseModel && model.responseModel.headers) {
|
||||
if (model.responseModel && model.responseModel.headers) {
|
||||
for (let i = 0; i < model.responseModel.headers.length; i++) {
|
||||
target.find('.response_headers').append(this.responseHeaderTemplate(model.responseModel.headers[i], i));
|
||||
}
|
||||
@@ -640,6 +675,14 @@ class APITester {
|
||||
|
||||
}
|
||||
|
||||
customHelper(event) {
|
||||
// Create and return the custom helper element
|
||||
let name = $(event.target).closest('.api_request_sortable').find('.open_api_request').text().trim();
|
||||
let apiId = $(event.target).closest('.api_request_sortable').data('id');
|
||||
return `<div style="display: flex; flex-direction: column; flex: 1; border: 2px dashed #333; padding: 10px;" data-id="${apiId}">
|
||||
<div>${name}</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
renderCollections() {
|
||||
let select = $('#modal_collection');
|
||||
@@ -654,6 +697,25 @@ class APITester {
|
||||
option.text(this.collections[i].name);
|
||||
select.append(option);
|
||||
}
|
||||
|
||||
$("li .api_request_sortable").draggable({
|
||||
helper: this.customHelper,
|
||||
start: function (event, ui) {
|
||||
// You can add any additional data or styles you want when dragging starts
|
||||
$(this).addClass('dragging');
|
||||
const apiDetails = {
|
||||
name: 'API 이름',
|
||||
method: 'POST',
|
||||
url: 'http://localhost:8080/api/test'
|
||||
};
|
||||
|
||||
},
|
||||
stop: function (event, ui) {
|
||||
// Clean up, e.g., remove styles or data
|
||||
$(this).removeClass('dragging');
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
renderCollection(collection, index) {
|
||||
@@ -661,7 +723,6 @@ class APITester {
|
||||
}
|
||||
|
||||
openTab(id) {
|
||||
//console.log('openTab: ' + id);
|
||||
try {
|
||||
$(`#api_request_tab_${id}`).tab('show'); // API request 탭 활성화
|
||||
} catch (e) {
|
||||
@@ -763,6 +824,7 @@ class APITester {
|
||||
target.find('.variables').empty();
|
||||
target.find('.variables').append(this.renderVariables(model.variables));
|
||||
}
|
||||
|
||||
parseParam(event) {
|
||||
const tabIndex = $('#apiRequestTabContent').children().index($(event.currentTarget).closest('.api_request'));
|
||||
let model = this.apiRequests[tabIndex];
|
||||
@@ -785,6 +847,7 @@ class APITester {
|
||||
this.renderQueryParamsView(tabIndex);
|
||||
}
|
||||
}
|
||||
|
||||
buildPath(event) {
|
||||
const tabIndex = $('#apiRequestTabContent').children().index($(event.currentTarget).closest('.api_request'));
|
||||
let model = this.apiRequests[tabIndex];
|
||||
@@ -813,14 +876,13 @@ class APITester {
|
||||
$("#loading-overlay").hide();
|
||||
}
|
||||
|
||||
sendApiRequest(event) {
|
||||
handleSendAPIRequest(event) {
|
||||
const tabIndex = $('#apiRequestTabContent').children().index($(event.currentTarget).closest('.api_request'));
|
||||
console.log(tabIndex);
|
||||
const me = this;
|
||||
|
||||
let model = this.apiRequests[tabIndex];
|
||||
|
||||
if (!model.server){
|
||||
if (!model.server) {
|
||||
$('.toast-body').text('서버를 등록해주세요.');
|
||||
$('.toast').toast('show');
|
||||
return;
|
||||
@@ -829,53 +891,42 @@ class APITester {
|
||||
let target = $('#api_request_' + model.id);
|
||||
target.find('.response_headers').empty();
|
||||
this.responseEditors[tabIndex].setValue('');
|
||||
let startTime = new Date().getTime();
|
||||
|
||||
this.showLoadingOverlay();
|
||||
model.responseModel = {};
|
||||
this.showLoadingOverlay();
|
||||
|
||||
let processedRequest = this.executePreRequestScript(model, tabIndex,() => {
|
||||
processedRequest = this.replacePlaceholdersWithVariables(processedRequest, tabIndex);
|
||||
this.currentAjaxRequest = $.ajax({
|
||||
url: '/mgmt/api/test.do',
|
||||
type: 'POST',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify(processedRequest),
|
||||
success: (data) => {
|
||||
model.responseModel.status = data.status;
|
||||
model.responseModel.body = data.body;
|
||||
model.responseModel.headers = data.headers;
|
||||
model.responseModel.size = data.size;
|
||||
let startTime = new Date().getTime();
|
||||
this.currentAjaxRequest = this.apiClient.sendAPIRequest(model)
|
||||
.then(response => {
|
||||
if (response) {
|
||||
model.responseModel = response;
|
||||
let endTime = new Date().getTime();
|
||||
model.responseModel.time = endTime - startTime;
|
||||
} else {
|
||||
model.responseModel = {
|
||||
status: 0,
|
||||
time: 0,
|
||||
size: 0,
|
||||
headers: [],
|
||||
body: ''
|
||||
};
|
||||
}
|
||||
|
||||
let response = {};
|
||||
response.body = data.body;
|
||||
response.status = data.status;
|
||||
response.headers = {};
|
||||
response.size = data.size;
|
||||
_.forEach(data.headers, (header) => {
|
||||
response.headers[header.key] = header.value;
|
||||
});
|
||||
|
||||
|
||||
this.executePostRequestScript(model.postRequestScript, tabIndex, response, ()=> {
|
||||
let endTime = new Date().getTime();
|
||||
model.responseModel.time = endTime - startTime;
|
||||
me.renderResponse(tabIndex);
|
||||
me.hideLoadingOverlay();
|
||||
});
|
||||
},
|
||||
error: (response, textStatus, errorThrown) => {
|
||||
me.hideLoadingOverlay();
|
||||
$('.toast-body').text(response.responseJSON.error);
|
||||
this.renderResponse(tabIndex);
|
||||
this.hideLoadingOverlay();
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error.name)
|
||||
if (error.name === 'AbortError') {
|
||||
console.log('Fetch aborted');
|
||||
} else {
|
||||
console.log('error3')
|
||||
$('.toast-body').text(error);
|
||||
$('.toast').toast('show');
|
||||
}
|
||||
this.hideLoadingOverlay();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
loadCollections() {
|
||||
const me = this;
|
||||
this.currentAjaxRequest = $.ajax({
|
||||
@@ -911,9 +962,6 @@ class APITester {
|
||||
type: 'POST',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify({name: name}),
|
||||
success: function (data) {
|
||||
|
||||
},
|
||||
error: function (response, textStatus, errorThrown) {
|
||||
me.hideLoadingOverlay();
|
||||
$('.toast-body').text(response.responseJSON.error);
|
||||
@@ -1046,8 +1094,8 @@ class APITester {
|
||||
queryParams: [],
|
||||
variables: [],
|
||||
requestBody: '',
|
||||
preRequestScript :'',
|
||||
postRequestScript :'',
|
||||
preRequestScript: '',
|
||||
postRequestScript: '',
|
||||
collectionId: collectionId,
|
||||
responseModel: {
|
||||
status: 0,
|
||||
@@ -1088,9 +1136,14 @@ class APITester {
|
||||
|
||||
cancelAjaxRequest() {
|
||||
if (this.currentAjaxRequest) {
|
||||
this.currentAjaxRequest.abort();
|
||||
this.hideLoadingOverlay();
|
||||
try {
|
||||
|
||||
this.currentAjaxRequest.abort();
|
||||
} catch (e) {
|
||||
this.apiClient.abort();
|
||||
}
|
||||
}
|
||||
this.hideLoadingOverlay();
|
||||
}
|
||||
|
||||
openApiRequest(event) {
|
||||
@@ -1147,7 +1200,7 @@ class APITester {
|
||||
return api.id === apiId;
|
||||
});
|
||||
console.log(apiIndex);
|
||||
if(apiIndex >= 0){
|
||||
if (apiIndex >= 0) {
|
||||
this.closeTabWithApiIndex(apiIndex);
|
||||
}
|
||||
const me = this;
|
||||
@@ -1172,7 +1225,7 @@ class APITester {
|
||||
|
||||
closeTabWithApiIndex(index) {
|
||||
console.log(index);
|
||||
if (index !== undefined){
|
||||
if (index !== undefined) {
|
||||
//console.log('closeTabWithApiIndex: ' + index);
|
||||
const model = this.apiRequests[index];
|
||||
console.log(model);
|
||||
@@ -1186,103 +1239,11 @@ class APITester {
|
||||
$(`#apiRequestTabTitle li:eq(0) button`).tab('show');
|
||||
}
|
||||
}
|
||||
|
||||
closeTab(event) {
|
||||
const index = $('#apiRequestTabTitle').children().index($(event.currentTarget).closest('.nav-item'));
|
||||
this.closeTabWithApiIndex(index);
|
||||
}
|
||||
|
||||
replacePlaceholdersWithVariables(original, index) {
|
||||
let request = JSON.parse(JSON.stringify(original));
|
||||
|
||||
let mergedVariables = {};
|
||||
_.forEach(this.globalVariables, (value, key) => {
|
||||
mergedVariables[key] = value;
|
||||
});
|
||||
|
||||
if (this.variables[index]) {
|
||||
_.forEach(this.variables[index], (value, key) => {
|
||||
mergedVariables[key] = value;
|
||||
});
|
||||
}
|
||||
|
||||
_.forEach(mergedVariables, (value, key) => {
|
||||
const placeholder = `{{${key}}}`;
|
||||
// Replace in path
|
||||
request.path = request.path.replace(new RegExp(placeholder, 'g'), value);
|
||||
|
||||
// Replace in requestBody
|
||||
if (request.requestBody) {
|
||||
request.requestBody = request.requestBody.replace(new RegExp(placeholder, 'g'), value);
|
||||
}
|
||||
|
||||
// Replace in headers
|
||||
if (request.headers) {
|
||||
request.headers = request.headers.map(header => {
|
||||
return {
|
||||
...header,
|
||||
key: header.key.replace(new RegExp(placeholder, 'g'), value),
|
||||
value: header.value.replace(new RegExp(placeholder, 'g'), value)
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
// Replace in queryParams
|
||||
if (request.queryParams) {
|
||||
request.queryParams = request.queryParams.map(queryParam => {
|
||||
return {
|
||||
...queryParam,
|
||||
key: queryParam.key.replace(new RegExp(placeholder, 'g'), value),
|
||||
value: queryParam.value.replace(new RegExp(placeholder, 'g'), value)
|
||||
};
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
executePreRequestScript(model, index, callback) {
|
||||
let script = model.preRequestScript;
|
||||
let resultFrame = document.getElementById('preRequest');
|
||||
let {headers, method, path, queryParams, requestBody} = model;
|
||||
window.request = {headers, method, path, queryParams, requestBody};
|
||||
this.variables[index] = {};
|
||||
model.variables.forEach((item) =>{
|
||||
if (item.enabled) {
|
||||
this.variables[index][item.key] = item.value;
|
||||
}
|
||||
});
|
||||
|
||||
window.preRequestComplete = function(updatedModel) {
|
||||
callback(updatedModel);
|
||||
};
|
||||
window.temp_variable = this.variables[index];
|
||||
|
||||
resultFrame.srcdoc = `<script>
|
||||
window.globals = window.parent.globals;
|
||||
window.variables = window.parent.temp_variable;
|
||||
window.request = window.parent.request;
|
||||
${script}
|
||||
window.parent.preRequestComplete(window.request);
|
||||
</script>`;
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
executePostRequestScript(script, index, response, callback) {
|
||||
let resultFrame = document.getElementById('postRequest');
|
||||
window.response = response;
|
||||
window.parent.temp_variable = this.variables[index];
|
||||
window.postRequestComplete = function(updatedModel) {
|
||||
callback(updatedModel);
|
||||
};
|
||||
window.temp_variable = this.variables[index];
|
||||
resultFrame.srcdoc = `<script>
|
||||
window.globals = window.parent.globals;
|
||||
window.variables = window.parent.temp_variable;
|
||||
window.response = window.parent.response;
|
||||
${script}
|
||||
window.parent.postRequestComplete(window.request);
|
||||
</script>`;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user