From 32db18520b806af076de4627081caaa6d4a47a4c Mon Sep 17 00:00:00 2001 From: Muhammad Ibragimov Date: Thu, 19 May 2022 13:56:03 +0500 Subject: [PATCH 01/18] [wip] show status code/text in editor output for multiple requests --- .../network_request_status_bar.tsx | 4 ++- .../application/containers/main/main.tsx | 2 ++ .../use_send_current_request/send_request.ts | 4 +-- .../legacy_core_editor/create_readonly.ts | 3 +- .../mode/output_highlight_rules.js | 23 ++++++++++-- src/plugins/console/public/styles/_app.scss | 36 +++++++++++++++++++ 6 files changed, 66 insertions(+), 6 deletions(-) diff --git a/src/plugins/console/public/application/components/network_request_status_bar/network_request_status_bar.tsx b/src/plugins/console/public/application/components/network_request_status_bar/network_request_status_bar.tsx index d5d8d97a4712a..12c1f12708990 100644 --- a/src/plugins/console/public/application/components/network_request_status_bar/network_request_status_bar.tsx +++ b/src/plugins/console/public/application/components/network_request_status_bar/network_request_status_bar.tsx @@ -28,6 +28,7 @@ export interface Props { // The time, in milliseconds, that the last request took timeElapsedMs: number; }; + isMultipleRequest: boolean; } const mapStatusCodeToBadgeColor = (statusCode: number) => { @@ -53,6 +54,7 @@ const mapStatusCodeToBadgeColor = (statusCode: number) => { export const NetworkRequestStatusBar: FunctionComponent = ({ requestInProgress, requestResult, + isMultipleRequest, }) => { let content: React.ReactNode = null; @@ -66,7 +68,7 @@ export const NetworkRequestStatusBar: FunctionComponent = ({ ); - } else if (requestResult) { + } else if (requestResult && !isMultipleRequest) { const { endpoint, method, statusCode, statusText, timeElapsedMs } = requestResult; content = ( diff --git a/src/plugins/console/public/application/containers/main/main.tsx b/src/plugins/console/public/application/containers/main/main.tsx index 5895b919f9842..21b643bc9e299 100644 --- a/src/plugins/console/public/application/containers/main/main.tsx +++ b/src/plugins/console/public/application/containers/main/main.tsx @@ -63,6 +63,7 @@ export function Main() { } const lastDatum = requestData?.[requestData.length - 1] ?? requestError; + const isMultipleRequest = (requestData && requestData.length > 1) ?? false; return (
@@ -105,6 +106,7 @@ export function Main() { } : undefined } + isMultipleRequest={isMultipleRequest} /> diff --git a/src/plugins/console/public/application/hooks/use_send_current_request/send_request.ts b/src/plugins/console/public/application/hooks/use_send_current_request/send_request.ts index 1ac47df30fca5..a083f50b274d1 100644 --- a/src/plugins/console/public/application/hooks/use_send_current_request/send_request.ts +++ b/src/plugins/console/public/application/hooks/use_send_current_request/send_request.ts @@ -106,7 +106,7 @@ export function sendRequest(args: RequestArgs): Promise { } if (isMultiRequest) { - value = '# ' + req.method + ' ' + req.url + '\n' + value; + value = '# ' + req.method + ' ' + req.url + ' ' + response.status + ' ' + response.statusText + '\n' + value; } results.push({ @@ -141,7 +141,7 @@ export function sendRequest(args: RequestArgs): Promise { } if (isMultiRequest) { - value = '# ' + req.method + ' ' + req.url + '\n' + value; + value = '# ' + req.method + ' ' + req.url + ' ' + statusCode + ' ' + statusText + '\n' + value; } const result = { diff --git a/src/plugins/console/public/application/models/legacy_core_editor/create_readonly.ts b/src/plugins/console/public/application/models/legacy_core_editor/create_readonly.ts index 2b87331d5f47d..ab0e5d69f3f98 100644 --- a/src/plugins/console/public/application/models/legacy_core_editor/create_readonly.ts +++ b/src/plugins/console/public/application/models/legacy_core_editor/create_readonly.ts @@ -36,7 +36,8 @@ export function createReadOnlyAceEditor(element: HTMLElement): CustomAceEditor { const session = output.getSession(); - session.setMode(val ? mode || outputMode : 'ace/mode/text'); + // session.setMode(val ? mode || outputMode : 'ace/mode/text'); + session.setMode(outputMode); session.setValue(val); if (typeof cb === 'function') { setTimeout(cb); diff --git a/src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.js b/src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.js index ebcce29da9e1e..9ecfb0b3d9dc8 100644 --- a/src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.js +++ b/src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.js @@ -24,9 +24,28 @@ export function OutputJsonHighlightRules() { regex: '#!.*$', }, { - token: 'comment', - regex: '#.*$', + token: function (value) { + const status = value.match(/\d+/g); + if (status <= 199) { + return 'badge.badge-default'; + } + if (status <= 299) { + return 'badge.badge-success'; + } + if (status <= 399) { + return 'badge.badge-primary'; + } + if (status <= 499) { + return 'badge.badge-warning'; + } + return 'badge.badge-danger'; + }, + regex: /(\d+\s(OK|Bad Request|Not Found|Continue|Created))$/, } + // { + // token: 'comment', + // regex: '#.*$', + // } ); if (this.constructor === OutputJsonHighlightRules) { diff --git a/src/plugins/console/public/styles/_app.scss b/src/plugins/console/public/styles/_app.scss index 61dc31138c768..e64cd4521bd90 100644 --- a/src/plugins/console/public/styles/_app.scss +++ b/src/plugins/console/public/styles/_app.scss @@ -33,6 +33,42 @@ .conApp__output { display: flex; flex: 1 1 1px; + + .ace_badge { + font-size: 12px; + font-weight: 500; + line-height: 18px; + padding: 0 8px; + display: inline-block; + text-decoration: none; + border-radius: 3px; + border: solid 1px transparent; + white-space: nowrap; + vertical-align: middle; + cursor: default; + max-width: 100%; + text-align: left; + } + + .ace_badge-success { + background-color: $euiColorSuccess; + } + + .ace_badge-primary { + background-color: $euiColorPrimary; + } + + .ace_badge-default { + background-color: $euiColorGhost; + } + + .ace_badge-warning { + background-color: $euiColorWarning; + } + + .ace_badge-danger { + background-color: $euiColorDanger; + } } .conApp__editorContent, From df0b1e2d511539a9fadab92efd2eabaa87f54f50 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Thu, 19 May 2022 09:03:47 +0000 Subject: [PATCH 02/18] [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' --- .../use_send_current_request/send_request.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/plugins/console/public/application/hooks/use_send_current_request/send_request.ts b/src/plugins/console/public/application/hooks/use_send_current_request/send_request.ts index a083f50b274d1..4795bd44c65a0 100644 --- a/src/plugins/console/public/application/hooks/use_send_current_request/send_request.ts +++ b/src/plugins/console/public/application/hooks/use_send_current_request/send_request.ts @@ -106,7 +106,17 @@ export function sendRequest(args: RequestArgs): Promise { } if (isMultiRequest) { - value = '# ' + req.method + ' ' + req.url + ' ' + response.status + ' ' + response.statusText + '\n' + value; + value = + '# ' + + req.method + + ' ' + + req.url + + ' ' + + response.status + + ' ' + + response.statusText + + '\n' + + value; } results.push({ @@ -141,7 +151,8 @@ export function sendRequest(args: RequestArgs): Promise { } if (isMultiRequest) { - value = '# ' + req.method + ' ' + req.url + ' ' + statusCode + ' ' + statusText + '\n' + value; + value = + '# ' + req.method + ' ' + req.url + ' ' + statusCode + ' ' + statusText + '\n' + value; } const result = { From a63deb52f0e97975944270067f374e8441f2ce30 Mon Sep 17 00:00:00 2001 From: Muhammad Ibragimov Date: Fri, 20 May 2022 16:44:22 +0500 Subject: [PATCH 03/18] Render status badges in the output panel --- .../network_request_status_bar.tsx | 1 + .../editor/legacy/console_editor/editor_output.tsx | 8 +++++++- .../models/legacy_core_editor/create_readonly.ts | 3 +-- .../mode/output_highlight_rules.js | 14 +++++++++----- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/plugins/console/public/application/components/network_request_status_bar/network_request_status_bar.tsx b/src/plugins/console/public/application/components/network_request_status_bar/network_request_status_bar.tsx index 12c1f12708990..bb7aecf5fc477 100644 --- a/src/plugins/console/public/application/components/network_request_status_bar/network_request_status_bar.tsx +++ b/src/plugins/console/public/application/components/network_request_status_bar/network_request_status_bar.tsx @@ -68,6 +68,7 @@ export const NetworkRequestStatusBar: FunctionComponent = ({ ); + // If multiple requests are sent, we do not need to render status badges since they are displayed in the editor output panel } else if (requestResult && !isMultipleRequest) { const { endpoint, method, statusCode, statusText, timeElapsedMs } = requestResult; diff --git a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor_output.tsx b/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor_output.tsx index 0817b6df5f7ef..b1ced97ece418 100644 --- a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor_output.tsx +++ b/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor_output.tsx @@ -11,6 +11,8 @@ import { EuiScreenReaderOnly } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React, { useEffect, useRef } from 'react'; import { convertMapboxVectorTileToJson } from './mapbox_vector_tile'; +// @ts-ignore +import * as OutputMode from '../../../../models/legacy_core_editor/mode/output'; // Ensure the modes we might switch to dynamically are available import 'brace/mode/text'; @@ -66,6 +68,7 @@ function EditorOutputUI() { lastResult: { data, error }, } = useRequestReadContext(); const inputId = 'ConAppOutputTextarea'; + const multiRequestOutputMode = new OutputMode.Mode(); useEffect(() => { editorInstanceRef.current = createReadOnlyAceEditor(editorRef.current!); @@ -83,7 +86,10 @@ function EditorOutputUI() { useEffect(() => { const editor = editorInstanceRef.current!; if (data) { - const mode = modeForContentType(data[0].response.contentType); + const isMultipleRequest = data.length > 1; + const mode = isMultipleRequest + ? multiRequestOutputMode + : modeForContentType(data[0].response.contentType); editor.update( data .map((result) => { diff --git a/src/plugins/console/public/application/models/legacy_core_editor/create_readonly.ts b/src/plugins/console/public/application/models/legacy_core_editor/create_readonly.ts index ab0e5d69f3f98..2b87331d5f47d 100644 --- a/src/plugins/console/public/application/models/legacy_core_editor/create_readonly.ts +++ b/src/plugins/console/public/application/models/legacy_core_editor/create_readonly.ts @@ -36,8 +36,7 @@ export function createReadOnlyAceEditor(element: HTMLElement): CustomAceEditor { const session = output.getSession(); - // session.setMode(val ? mode || outputMode : 'ace/mode/text'); - session.setMode(outputMode); + session.setMode(val ? mode || outputMode : 'ace/mode/text'); session.setValue(val); if (typeof cb === 'function') { setTimeout(cb); diff --git a/src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.js b/src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.js index 9ecfb0b3d9dc8..4fb0e98614acc 100644 --- a/src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.js +++ b/src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.js @@ -23,9 +23,16 @@ export function OutputJsonHighlightRules() { token: 'warning', regex: '#!.*$', }, + { + token: 'comment', + /* Comments start with '#' character and end where characters start with http status and statusText + * This will allow us to tokenize the status badges for highlighting the multiple request results in editor output + */ + regex: /#(.*?)(?=\d+\s(?:OK|Bad Request|Not Found|Continue|Created)|$)/, + }, { token: function (value) { - const status = value.match(/\d+/g); + const status = value.match(/\d+/); if (status <= 199) { return 'badge.badge-default'; } @@ -40,12 +47,9 @@ export function OutputJsonHighlightRules() { } return 'badge.badge-danger'; }, + // Matches any digits ending with http statusText at the end of string regex: /(\d+\s(OK|Bad Request|Not Found|Continue|Created))$/, } - // { - // token: 'comment', - // regex: '#.*$', - // } ); if (this.constructor === OutputJsonHighlightRules) { From 0bf0c1a4b1257de252f71e1652ea4104117f7520 Mon Sep 17 00:00:00 2001 From: Muhammad Ibragimov Date: Fri, 20 May 2022 16:52:44 +0500 Subject: [PATCH 04/18] Add missing dependancy for useEffect hook --- .../containers/editor/legacy/console_editor/editor_output.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor_output.tsx b/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor_output.tsx index b1ced97ece418..35a098649d6b0 100644 --- a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor_output.tsx +++ b/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor_output.tsx @@ -117,7 +117,7 @@ function EditorOutputUI() { } else { editor.update(''); } - }, [readOnlySettings, data, error]); + }, [readOnlySettings, data, error, multiRequestOutputMode]); useEffect(() => { applyCurrentSettings(editorInstanceRef.current!, readOnlySettings); From 215eb444e240abdc877edfd12d35b7864b899cfc Mon Sep 17 00:00:00 2001 From: Muhammad Ibragimov Date: Fri, 20 May 2022 17:02:03 +0500 Subject: [PATCH 05/18] Lint --- .../containers/editor/legacy/console_editor/editor_output.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor_output.tsx b/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor_output.tsx index 35a098649d6b0..9c2cd3e342396 100644 --- a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor_output.tsx +++ b/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor_output.tsx @@ -68,7 +68,6 @@ function EditorOutputUI() { lastResult: { data, error }, } = useRequestReadContext(); const inputId = 'ConAppOutputTextarea'; - const multiRequestOutputMode = new OutputMode.Mode(); useEffect(() => { editorInstanceRef.current = createReadOnlyAceEditor(editorRef.current!); @@ -84,6 +83,7 @@ function EditorOutputUI() { }, [services.settings]); useEffect(() => { + const multiRequestOutputMode = new OutputMode.Mode(); const editor = editorInstanceRef.current!; if (data) { const isMultipleRequest = data.length > 1; @@ -117,7 +117,7 @@ function EditorOutputUI() { } else { editor.update(''); } - }, [readOnlySettings, data, error, multiRequestOutputMode]); + }, [readOnlySettings, data, error]); useEffect(() => { applyCurrentSettings(editorInstanceRef.current!, readOnlySettings); From ad63eafe65680d6ec940d6e3f36ded17feabb20b Mon Sep 17 00:00:00 2001 From: Muhammad Ibragimov Date: Tue, 24 May 2022 13:57:33 +0500 Subject: [PATCH 06/18] Address comments --- .../network_request_status_bar.tsx | 5 +---- .../legacy/console_editor/editor_output.tsx | 5 ++--- .../application/containers/main/main.tsx | 2 -- .../use_send_current_request/send_request.ts | 20 ++++--------------- .../mode/output_highlight_rules.js | 8 ++------ src/plugins/console/public/styles/_app.scss | 5 +++++ 6 files changed, 14 insertions(+), 31 deletions(-) diff --git a/src/plugins/console/public/application/components/network_request_status_bar/network_request_status_bar.tsx b/src/plugins/console/public/application/components/network_request_status_bar/network_request_status_bar.tsx index bb7aecf5fc477..d5d8d97a4712a 100644 --- a/src/plugins/console/public/application/components/network_request_status_bar/network_request_status_bar.tsx +++ b/src/plugins/console/public/application/components/network_request_status_bar/network_request_status_bar.tsx @@ -28,7 +28,6 @@ export interface Props { // The time, in milliseconds, that the last request took timeElapsedMs: number; }; - isMultipleRequest: boolean; } const mapStatusCodeToBadgeColor = (statusCode: number) => { @@ -54,7 +53,6 @@ const mapStatusCodeToBadgeColor = (statusCode: number) => { export const NetworkRequestStatusBar: FunctionComponent = ({ requestInProgress, requestResult, - isMultipleRequest, }) => { let content: React.ReactNode = null; @@ -68,8 +66,7 @@ export const NetworkRequestStatusBar: FunctionComponent = ({ ); - // If multiple requests are sent, we do not need to render status badges since they are displayed in the editor output panel - } else if (requestResult && !isMultipleRequest) { + } else if (requestResult) { const { endpoint, method, statusCode, statusText, timeElapsedMs } = requestResult; content = ( diff --git a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor_output.tsx b/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor_output.tsx index 9c2cd3e342396..d4a689d0bfb78 100644 --- a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor_output.tsx +++ b/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor_output.tsx @@ -12,7 +12,7 @@ import { i18n } from '@kbn/i18n'; import React, { useEffect, useRef } from 'react'; import { convertMapboxVectorTileToJson } from './mapbox_vector_tile'; // @ts-ignore -import * as OutputMode from '../../../../models/legacy_core_editor/mode/output'; +import { Mode } from '../../../../models/legacy_core_editor/mode/output'; // Ensure the modes we might switch to dynamically are available import 'brace/mode/text'; @@ -83,12 +83,11 @@ function EditorOutputUI() { }, [services.settings]); useEffect(() => { - const multiRequestOutputMode = new OutputMode.Mode(); const editor = editorInstanceRef.current!; if (data) { const isMultipleRequest = data.length > 1; const mode = isMultipleRequest - ? multiRequestOutputMode + ? new Mode() : modeForContentType(data[0].response.contentType); editor.update( data diff --git a/src/plugins/console/public/application/containers/main/main.tsx b/src/plugins/console/public/application/containers/main/main.tsx index 21b643bc9e299..5895b919f9842 100644 --- a/src/plugins/console/public/application/containers/main/main.tsx +++ b/src/plugins/console/public/application/containers/main/main.tsx @@ -63,7 +63,6 @@ export function Main() { } const lastDatum = requestData?.[requestData.length - 1] ?? requestError; - const isMultipleRequest = (requestData && requestData.length > 1) ?? false; return (
@@ -106,7 +105,6 @@ export function Main() { } : undefined } - isMultipleRequest={isMultipleRequest} /> diff --git a/src/plugins/console/public/application/hooks/use_send_current_request/send_request.ts b/src/plugins/console/public/application/hooks/use_send_current_request/send_request.ts index 4795bd44c65a0..3247c8aed164e 100644 --- a/src/plugins/console/public/application/hooks/use_send_current_request/send_request.ts +++ b/src/plugins/console/public/application/hooks/use_send_current_request/send_request.ts @@ -9,8 +9,7 @@ import type { HttpSetup, IHttpFetchError } from '@kbn/core/public'; import { XJson } from '@kbn/es-ui-shared-plugin/public'; import { extractWarningMessages } from '../../../lib/utils'; -// @ts-ignore -import * as es from '../../../lib/es/es'; +import { send } from '../../../lib/es/es'; import { BaseResponseType } from '../../../types'; const { collapseLiteralStrings } = XJson; @@ -72,7 +71,7 @@ export function sendRequest(args: RequestArgs): Promise { const startTime = Date.now(); try { - const { response, body } = await es.send({ + const { response, body } = await send({ http: args.http, method, path, @@ -106,17 +105,7 @@ export function sendRequest(args: RequestArgs): Promise { } if (isMultiRequest) { - value = - '# ' + - req.method + - ' ' + - req.url + - ' ' + - response.status + - ' ' + - response.statusText + - '\n' + - value; + value = `# ${req.method} ${req.url} ${response.status} ${response.statusText}\n${value}`; } results.push({ @@ -151,8 +140,7 @@ export function sendRequest(args: RequestArgs): Promise { } if (isMultiRequest) { - value = - '# ' + req.method + ' ' + req.url + ' ' + statusCode + ' ' + statusText + '\n' + value; + value = `# ${req.method} ${req.url} ${statusCode} ${statusText}\n${value}`; } const result = { diff --git a/src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.js b/src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.js index 4fb0e98614acc..9c43377a67942 100644 --- a/src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.js +++ b/src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.js @@ -25,10 +25,7 @@ export function OutputJsonHighlightRules() { }, { token: 'comment', - /* Comments start with '#' character and end where characters start with http status and statusText - * This will allow us to tokenize the status badges for highlighting the multiple request results in editor output - */ - regex: /#(.*?)(?=\d+\s(?:OK|Bad Request|Not Found|Continue|Created)|$)/, + regex: /#(.*?)(?=\d+\s(?:[\sA-Za-z]+)|$)/, }, { token: function (value) { @@ -47,8 +44,7 @@ export function OutputJsonHighlightRules() { } return 'badge.badge-danger'; }, - // Matches any digits ending with http statusText at the end of string - regex: /(\d+\s(OK|Bad Request|Not Found|Continue|Created))$/, + regex: /(\d+\s[\sA-Za-z]+$)/, } ); diff --git a/src/plugins/console/public/styles/_app.scss b/src/plugins/console/public/styles/_app.scss index e64cd4521bd90..58555722979e6 100644 --- a/src/plugins/console/public/styles/_app.scss +++ b/src/plugins/console/public/styles/_app.scss @@ -52,22 +52,27 @@ .ace_badge-success { background-color: $euiColorSuccess; + color: chooseLightOrDarkText($euiColorSuccess); } .ace_badge-primary { background-color: $euiColorPrimary; + color: chooseLightOrDarkText($euiColorPrimary); } .ace_badge-default { background-color: $euiColorGhost; + color: chooseLightOrDarkText($euiColorGhost); } .ace_badge-warning { background-color: $euiColorWarning; + color: chooseLightOrDarkText($euiColorWarning); } .ace_badge-danger { background-color: $euiColorDanger; + color: chooseLightOrDarkText($euiColorDanger); } } From ed198f880496f2a3f7f256d68aa99185d1b511fa Mon Sep 17 00:00:00 2001 From: Muhammad Ibragimov Date: Tue, 24 May 2022 15:37:00 +0500 Subject: [PATCH 07/18] Add functional tests --- test/functional/apps/console/_console.ts | 30 ++++++++++++++++++++ test/functional/page_objects/console_page.ts | 23 +++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/test/functional/apps/console/_console.ts b/test/functional/apps/console/_console.ts index 52218b88be60d..939b964456413 100644 --- a/test/functional/apps/console/_console.ts +++ b/test/functional/apps/console/_console.ts @@ -122,5 +122,35 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); }); }); + + describe('multiple requests output', () => { + const sendRequests = async () => { + await PageObjects.console.enterRequest('\n PUT test-index'); + await PageObjects.console.enterRequest('\n DELETE test-index'); + await PageObjects.console.selectAllRequests(); + await PageObjects.console.clickPlay(); + }; + beforeEach(async () => { + await PageObjects.console.clearTextArea(); + }); + it('should contain comments starting with # symbol', async () => { + await sendRequests(); + + await retry.try(async () => { + const response = await PageObjects.console.getResponse(); + log.debug(response); + expect(response).to.contain('# PUT test-index 200 OK'); + expect(response).to.contain('# DELETE test-index 200 OK'); + }); + }); + it('should display status badges', async () => { + // This request should fail + await PageObjects.console.enterRequest('\n GET test-index'); + await sendRequests(); + + await retry.waitFor('success badge', () => PageObjects.console.hasSuccessBadge()); + await retry.waitFor('warning badge', () => PageObjects.console.hasWarningBadge()); + }); + }); }); } diff --git a/test/functional/page_objects/console_page.ts b/test/functional/page_objects/console_page.ts index 7aaf842f28d14..ab56348066378 100644 --- a/test/functional/page_objects/console_page.ts +++ b/test/functional/page_objects/console_page.ts @@ -151,4 +151,27 @@ export class ConsolePageObject extends FtrService { return lines.length === 1 && text.trim() === ''; }); } + + public async selectAllRequests() { + const textArea = await this.getEditorTextArea(); + await textArea.pressKeys([Key.COMMAND, 'A']); + } + + public async hasSuccessBadge(): Promise { + try { + const responseEditor = await this.testSubjects.find('response-editor'); + return Boolean(responseEditor.findByCssSelector('.ace_badge-success')); + } catch (e) { + return false; + } + } + + public async hasWarningBadge(): Promise { + try { + const responseEditor = await this.testSubjects.find('response-editor'); + return Boolean(responseEditor.findByCssSelector('.ace_badge-warning')); + } catch (e) { + return false; + } + } } From 962da8f27c021f05d3b67be82b2d3fec4c623ad4 Mon Sep 17 00:00:00 2001 From: Muhammad Ibragimov Date: Tue, 24 May 2022 16:21:05 +0500 Subject: [PATCH 08/18] Update tests --- test/functional/apps/console/_console.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/functional/apps/console/_console.ts b/test/functional/apps/console/_console.ts index 939b964456413..4dfe288302952 100644 --- a/test/functional/apps/console/_console.ts +++ b/test/functional/apps/console/_console.ts @@ -125,8 +125,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('multiple requests output', () => { const sendRequests = async () => { - await PageObjects.console.enterRequest('\n PUT test-index'); - await PageObjects.console.enterRequest('\n DELETE test-index'); + await PageObjects.console.enterRequest('\n PUT test-index-1'); + await PageObjects.console.enterRequest('\n PUT test-index-2'); await PageObjects.console.selectAllRequests(); await PageObjects.console.clickPlay(); }; @@ -139,8 +139,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await retry.try(async () => { const response = await PageObjects.console.getResponse(); log.debug(response); - expect(response).to.contain('# PUT test-index 200 OK'); - expect(response).to.contain('# DELETE test-index 200 OK'); + expect(response).to.contain('# PUT test-index-1 200 OK'); + expect(response).to.contain('# PUT test-index-2 200 OK'); }); }); it('should display status badges', async () => { From 5a0d90701a7929bc2034bb415b4c958f680b57de Mon Sep 17 00:00:00 2001 From: Muhammad Ibragimov Date: Tue, 24 May 2022 16:26:12 +0500 Subject: [PATCH 09/18] Fix tests --- test/functional/apps/console/_console.ts | 8 ++++---- test/functional/page_objects/console_page.ts | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test/functional/apps/console/_console.ts b/test/functional/apps/console/_console.ts index 4dfe288302952..939b964456413 100644 --- a/test/functional/apps/console/_console.ts +++ b/test/functional/apps/console/_console.ts @@ -125,8 +125,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('multiple requests output', () => { const sendRequests = async () => { - await PageObjects.console.enterRequest('\n PUT test-index-1'); - await PageObjects.console.enterRequest('\n PUT test-index-2'); + await PageObjects.console.enterRequest('\n PUT test-index'); + await PageObjects.console.enterRequest('\n DELETE test-index'); await PageObjects.console.selectAllRequests(); await PageObjects.console.clickPlay(); }; @@ -139,8 +139,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await retry.try(async () => { const response = await PageObjects.console.getResponse(); log.debug(response); - expect(response).to.contain('# PUT test-index-1 200 OK'); - expect(response).to.contain('# PUT test-index-2 200 OK'); + expect(response).to.contain('# PUT test-index 200 OK'); + expect(response).to.contain('# DELETE test-index 200 OK'); }); }); it('should display status badges', async () => { diff --git a/test/functional/page_objects/console_page.ts b/test/functional/page_objects/console_page.ts index ab56348066378..2deaffd185bf2 100644 --- a/test/functional/page_objects/console_page.ts +++ b/test/functional/page_objects/console_page.ts @@ -154,7 +154,7 @@ export class ConsolePageObject extends FtrService { public async selectAllRequests() { const textArea = await this.getEditorTextArea(); - await textArea.pressKeys([Key.COMMAND, 'A']); + await textArea.pressKeys([Key.CONTROL, Key.COMMAND, 'A']); } public async hasSuccessBadge(): Promise { From 574bf1d7c94d51f60513d403a675f26764832344 Mon Sep 17 00:00:00 2001 From: Muhammad Ibragimov Date: Tue, 24 May 2022 16:31:25 +0500 Subject: [PATCH 10/18] Update selectAll command key for firefox --- test/functional/page_objects/console_page.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/functional/page_objects/console_page.ts b/test/functional/page_objects/console_page.ts index 2deaffd185bf2..7f2a21e2c2a73 100644 --- a/test/functional/page_objects/console_page.ts +++ b/test/functional/page_objects/console_page.ts @@ -14,6 +14,7 @@ export class ConsolePageObject extends FtrService { private readonly testSubjects = this.ctx.getService('testSubjects'); private readonly retry = this.ctx.getService('retry'); private readonly find = this.ctx.getService('find'); + private readonly browser = this.ctx.getService('browser'); public async getVisibleTextFromAceEditor(editor: WebElementWrapper) { const lines = await editor.findAllByClassName('ace_line_group'); @@ -154,7 +155,11 @@ export class ConsolePageObject extends FtrService { public async selectAllRequests() { const textArea = await this.getEditorTextArea(); - await textArea.pressKeys([Key.CONTROL, Key.COMMAND, 'A']); + if (this.browser.isFirefox) { + await textArea.pressKeys([Key.COMMAND, 'A']); + } else { + await textArea.pressKeys([Key.CONTROL, Key.COMMAND, 'A']); + } } public async hasSuccessBadge(): Promise { From da63f46f4a86190502d57a9f6d06c05ff46c39de Mon Sep 17 00:00:00 2001 From: Muhammad Ibragimov Date: Wed, 25 May 2022 11:53:28 +0500 Subject: [PATCH 11/18] Fix selecting all requests in tests --- test/functional/apps/console/_console.ts | 3 +-- test/functional/page_objects/console_page.ts | 10 +++------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/test/functional/apps/console/_console.ts b/test/functional/apps/console/_console.ts index 939b964456413..f6c7816f19673 100644 --- a/test/functional/apps/console/_console.ts +++ b/test/functional/apps/console/_console.ts @@ -135,7 +135,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('should contain comments starting with # symbol', async () => { await sendRequests(); - await retry.try(async () => { const response = await PageObjects.console.getResponse(); log.debug(response); @@ -146,8 +145,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('should display status badges', async () => { // This request should fail await PageObjects.console.enterRequest('\n GET test-index'); - await sendRequests(); + await sendRequests(); await retry.waitFor('success badge', () => PageObjects.console.hasSuccessBadge()); await retry.waitFor('warning badge', () => PageObjects.console.hasWarningBadge()); }); diff --git a/test/functional/page_objects/console_page.ts b/test/functional/page_objects/console_page.ts index a25f45328593a..b12b731dac5b2 100644 --- a/test/functional/page_objects/console_page.ts +++ b/test/functional/page_objects/console_page.ts @@ -14,7 +14,6 @@ export class ConsolePageObject extends FtrService { private readonly testSubjects = this.ctx.getService('testSubjects'); private readonly retry = this.ctx.getService('retry'); private readonly find = this.ctx.getService('find'); - private readonly browser = this.ctx.getService('browser'); public async getVisibleTextFromAceEditor(editor: WebElementWrapper) { const lines = await editor.findAllByClassName('ace_line_group'); @@ -166,12 +165,9 @@ export class ConsolePageObject extends FtrService { } public async selectAllRequests() { - const textArea = await this.getEditorTextArea(); - if (this.browser.isFirefox) { - await textArea.pressKeys([Key.COMMAND, 'A']); - } else { - await textArea.pressKeys([Key.CONTROL, Key.COMMAND, 'A']); - } + const editor = await this.getEditorTextArea(); + const selectionKey = Key[process.platform === 'darwin' ? 'COMMAND' : 'CONTROL']; + await editor.pressKeys([selectionKey, 'a']); } public async hasSuccessBadge(): Promise { From 0e72f31efef9b8e256172fd8cbfca80b851a6f7a Mon Sep 17 00:00:00 2001 From: Muhammad Ibragimov Date: Wed, 25 May 2022 14:22:26 +0500 Subject: [PATCH 12/18] Convert output modes to TS --- .../legacy/console_editor/editor_output.tsx | 1 - .../mode/{output.js => output.ts} | 17 +++--- .../mode/output_highlight_rules.js | 56 ------------------ .../mode/output_highlight_rules.ts | 57 +++++++++++++++++++ 4 files changed, 66 insertions(+), 65 deletions(-) rename src/plugins/console/public/application/models/legacy_core_editor/mode/{output.js => output.ts} (75%) delete mode 100644 src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.js create mode 100644 src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.ts diff --git a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor_output.tsx b/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor_output.tsx index d4a689d0bfb78..eb085248f4a3e 100644 --- a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor_output.tsx +++ b/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor_output.tsx @@ -11,7 +11,6 @@ import { EuiScreenReaderOnly } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React, { useEffect, useRef } from 'react'; import { convertMapboxVectorTileToJson } from './mapbox_vector_tile'; -// @ts-ignore import { Mode } from '../../../../models/legacy_core_editor/mode/output'; // Ensure the modes we might switch to dynamically are available diff --git a/src/plugins/console/public/application/models/legacy_core_editor/mode/output.js b/src/plugins/console/public/application/models/legacy_core_editor/mode/output.ts similarity index 75% rename from src/plugins/console/public/application/models/legacy_core_editor/mode/output.js rename to src/plugins/console/public/application/models/legacy_core_editor/mode/output.ts index b769505e81335..796a4f9d716dd 100644 --- a/src/plugins/console/public/application/models/legacy_core_editor/mode/output.js +++ b/src/plugins/console/public/application/models/legacy_core_editor/mode/output.ts @@ -10,7 +10,6 @@ import ace from 'brace'; import { OutputJsonHighlightRules } from './output_highlight_rules'; -const oop = ace.acequire('ace/lib/oop'); const JSONMode = ace.acequire('ace/mode/json').Mode; const MatchingBraceOutdent = ace.acequire('ace/mode/matching_brace_outdent').MatchingBraceOutdent; const CstyleBehaviour = ace.acequire('ace/mode/behaviour/cstyle').CstyleBehaviour; @@ -18,15 +17,17 @@ const CStyleFoldMode = ace.acequire('ace/mode/folding/cstyle').FoldMode; ace.acequire('ace/worker/worker_client'); const AceTokenizer = ace.acequire('ace/tokenizer').Tokenizer; -export function Mode() { - this.$tokenizer = new AceTokenizer(new OutputJsonHighlightRules().getRules()); - this.$outdent = new MatchingBraceOutdent(); - this.$behaviour = new CstyleBehaviour(); - this.foldingRules = new CStyleFoldMode(); +export class Mode extends JSONMode { + constructor() { + super(); + this.$tokenizer = new AceTokenizer(new OutputJsonHighlightRules().getRules()); + this.$outdent = new MatchingBraceOutdent(); + this.$behaviour = new CstyleBehaviour(); + this.foldingRules = new CStyleFoldMode(); + } } -oop.inherits(Mode, JSONMode); -(function () { +(function (this: any) { this.createWorker = function () { return null; }; diff --git a/src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.js b/src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.js deleted file mode 100644 index 9c43377a67942..0000000000000 --- a/src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.js +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import ace from 'brace'; -import 'brace/mode/json'; -import { addXJsonToRules } from '@kbn/ace'; - -const oop = ace.acequire('ace/lib/oop'); -const JsonHighlightRules = ace.acequire('ace/mode/json_highlight_rules').JsonHighlightRules; - -export function OutputJsonHighlightRules() { - this.$rules = {}; - - addXJsonToRules(this, 'start'); - - this.$rules.start.unshift( - { - token: 'warning', - regex: '#!.*$', - }, - { - token: 'comment', - regex: /#(.*?)(?=\d+\s(?:[\sA-Za-z]+)|$)/, - }, - { - token: function (value) { - const status = value.match(/\d+/); - if (status <= 199) { - return 'badge.badge-default'; - } - if (status <= 299) { - return 'badge.badge-success'; - } - if (status <= 399) { - return 'badge.badge-primary'; - } - if (status <= 499) { - return 'badge.badge-warning'; - } - return 'badge.badge-danger'; - }, - regex: /(\d+\s[\sA-Za-z]+$)/, - } - ); - - if (this.constructor === OutputJsonHighlightRules) { - this.normalizeRules(); - } -} - -oop.inherits(OutputJsonHighlightRules, JsonHighlightRules); diff --git a/src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.ts b/src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.ts new file mode 100644 index 0000000000000..8d1e9d6428c75 --- /dev/null +++ b/src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.ts @@ -0,0 +1,57 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import ace from 'brace'; +import 'brace/mode/json'; +import { addXJsonToRules } from '@kbn/ace'; + +const JsonHighlightRules = ace.acequire('ace/mode/json_highlight_rules').JsonHighlightRules; + +export class OutputJsonHighlightRules extends JsonHighlightRules { + constructor() { + super(); + this.$rules = {}; + addXJsonToRules(this, 'start'); + this.$rules.start.unshift( + { + token: 'warning', + regex: '#!.*$', + }, + { + token: 'comment', + regex: /#(.*?)(?=\d+\s(?:[\sA-Za-z]+)|$)/, + }, + { + token(value: string) { + const regExpMatchArray = value.match(/\d+/); + if (regExpMatchArray) { + const status = parseInt(regExpMatchArray[0], 10); + if (status <= 199) { + return 'badge.badge-default'; + } + if (status <= 299) { + return 'badge.badge-success'; + } + if (status <= 399) { + return 'badge.badge-primary'; + } + if (status <= 499) { + return 'badge.badge-warning'; + } + return 'badge.badge-danger'; + } + }, + regex: /(\d+\s[\sA-Za-z]+$)/, + } + ); + + if (this.constructor === OutputJsonHighlightRules) { + this.normalizeRules(); + } + } +} From 15d683e6f4488fabcbdc1a331ce37af050de85c7 Mon Sep 17 00:00:00 2001 From: Muhammad Ibragimov Date: Wed, 25 May 2022 15:36:19 +0500 Subject: [PATCH 13/18] Fix checks --- .../models/legacy_core_editor/create_readonly.ts | 7 +++---- .../legacy_core_editor/mode/output_highlight_rules.ts | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/plugins/console/public/application/models/legacy_core_editor/create_readonly.ts b/src/plugins/console/public/application/models/legacy_core_editor/create_readonly.ts index 2b87331d5f47d..6dbff63ec30ba 100644 --- a/src/plugins/console/public/application/models/legacy_core_editor/create_readonly.ts +++ b/src/plugins/console/public/application/models/legacy_core_editor/create_readonly.ts @@ -8,8 +8,7 @@ import _ from 'lodash'; import ace from 'brace'; -// @ts-ignore -import * as OutputMode from './mode/output'; +import { Mode } from './mode/output'; import smartResize from './smart_resize'; export interface CustomAceEditor extends ace.Editor { @@ -24,7 +23,7 @@ export interface CustomAceEditor extends ace.Editor { export function createReadOnlyAceEditor(element: HTMLElement): CustomAceEditor { const output: CustomAceEditor = ace.acequire('ace/ace').edit(element); - const outputMode = new OutputMode.Mode(); + const outputMode = new Mode(); output.$blockScrolling = Infinity; output.resize = smartResize(output); @@ -36,7 +35,7 @@ export function createReadOnlyAceEditor(element: HTMLElement): CustomAceEditor { const session = output.getSession(); - session.setMode(val ? mode || outputMode : 'ace/mode/text'); + session.setMode(val ? (mode as string) || (outputMode as unknown as string) : 'ace/mode/text'); session.setValue(val); if (typeof cb === 'function') { setTimeout(cb); diff --git a/src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.ts b/src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.ts index 8d1e9d6428c75..58e84ac9e8a0f 100644 --- a/src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.ts +++ b/src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.ts @@ -50,7 +50,7 @@ export class OutputJsonHighlightRules extends JsonHighlightRules { } ); - if (this.constructor === OutputJsonHighlightRules) { + if (this instanceof OutputJsonHighlightRules) { this.normalizeRules(); } } From 3aa00437c3cffdc258b27c7895386531f4a276b8 Mon Sep 17 00:00:00 2001 From: Muhammad Ibragimov Date: Thu, 26 May 2022 11:11:52 +0500 Subject: [PATCH 14/18] Address comments --- .../legacy_core_editor/create_readonly.ts | 7 +-- .../models/legacy_core_editor/mode/output.ts | 2 +- .../mode/output_highlight_rules.ts | 10 ++-- src/plugins/console/public/styles/_app.scss | 48 +++++++++---------- test/functional/apps/console/_console.ts | 25 +++++----- test/functional/page_objects/console_page.ts | 8 ++-- 6 files changed, 52 insertions(+), 48 deletions(-) diff --git a/src/plugins/console/public/application/models/legacy_core_editor/create_readonly.ts b/src/plugins/console/public/application/models/legacy_core_editor/create_readonly.ts index 6dbff63ec30ba..8b5af8e560519 100644 --- a/src/plugins/console/public/application/models/legacy_core_editor/create_readonly.ts +++ b/src/plugins/console/public/application/models/legacy_core_editor/create_readonly.ts @@ -12,7 +12,7 @@ import { Mode } from './mode/output'; import smartResize from './smart_resize'; export interface CustomAceEditor extends ace.Editor { - update: (text: string, mode?: unknown, cb?: () => void) => void; + update: (text: string, mode?: string | Mode, cb?: () => void) => void; append: (text: string, foldPrevious?: boolean, cb?: () => void) => void; } @@ -27,15 +27,16 @@ export function createReadOnlyAceEditor(element: HTMLElement): CustomAceEditor { output.$blockScrolling = Infinity; output.resize = smartResize(output); - output.update = (val: string, mode?: unknown, cb?: () => void) => { + output.update = (val: string, mode?: string | Mode, cb?: () => void) => { if (typeof mode === 'function') { cb = mode as () => void; mode = void 0; } const session = output.getSession(); + const currentMode = val ? mode || outputMode : 'ace/mode/text'; - session.setMode(val ? (mode as string) || (outputMode as unknown as string) : 'ace/mode/text'); + session.setMode(currentMode as string); session.setValue(val); if (typeof cb === 'function') { setTimeout(cb); diff --git a/src/plugins/console/public/application/models/legacy_core_editor/mode/output.ts b/src/plugins/console/public/application/models/legacy_core_editor/mode/output.ts index 796a4f9d716dd..234d57b830a7b 100644 --- a/src/plugins/console/public/application/models/legacy_core_editor/mode/output.ts +++ b/src/plugins/console/public/application/models/legacy_core_editor/mode/output.ts @@ -27,7 +27,7 @@ export class Mode extends JSONMode { } } -(function (this: any) { +(function (this: Mode) { this.createWorker = function () { return null; }; diff --git a/src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.ts b/src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.ts index 58e84ac9e8a0f..3c82100ef2e9d 100644 --- a/src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.ts +++ b/src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.ts @@ -32,18 +32,18 @@ export class OutputJsonHighlightRules extends JsonHighlightRules { if (regExpMatchArray) { const status = parseInt(regExpMatchArray[0], 10); if (status <= 199) { - return 'badge.badge-default'; + return 'badge.badge--default'; } if (status <= 299) { - return 'badge.badge-success'; + return 'badge.badge--success'; } if (status <= 399) { - return 'badge.badge-primary'; + return 'badge.badge--primary'; } if (status <= 499) { - return 'badge.badge-warning'; + return 'badge.badge--warning'; } - return 'badge.badge-danger'; + return 'badge.badge--danger'; } }, regex: /(\d+\s[\sA-Za-z]+$)/, diff --git a/src/plugins/console/public/styles/_app.scss b/src/plugins/console/public/styles/_app.scss index 58555722979e6..86873305bfb20 100644 --- a/src/plugins/console/public/styles/_app.scss +++ b/src/plugins/console/public/styles/_app.scss @@ -48,31 +48,31 @@ cursor: default; max-width: 100%; text-align: left; - } - - .ace_badge-success { - background-color: $euiColorSuccess; - color: chooseLightOrDarkText($euiColorSuccess); - } - - .ace_badge-primary { - background-color: $euiColorPrimary; - color: chooseLightOrDarkText($euiColorPrimary); - } - - .ace_badge-default { - background-color: $euiColorGhost; - color: chooseLightOrDarkText($euiColorGhost); - } - - .ace_badge-warning { - background-color: $euiColorWarning; - color: chooseLightOrDarkText($euiColorWarning); - } - .ace_badge-danger { - background-color: $euiColorDanger; - color: chooseLightOrDarkText($euiColorDanger); + &--success { + background-color: $euiColorSuccess; + color: chooseLightOrDarkText($euiColorSuccess); + } + + &--warning { + background-color: $euiColorWarning; + color: chooseLightOrDarkText($euiColorWarning); + } + + &--primary { + background-color: $euiColorPrimary; + color: chooseLightOrDarkText($euiColorPrimary); + } + + &--default { + background-color: $euiColorGhost; + color: chooseLightOrDarkText($euiColorGhost); + } + + &--danger { + background-color: $euiColorDanger; + color: chooseLightOrDarkText($euiColorDanger); + } } } diff --git a/test/functional/apps/console/_console.ts b/test/functional/apps/console/_console.ts index f6c7816f19673..126788c3312d2 100644 --- a/test/functional/apps/console/_console.ts +++ b/test/functional/apps/console/_console.ts @@ -7,6 +7,7 @@ */ import expect from '@kbn/expect'; +import { asyncForEach } from '@kbn/std'; import { FtrProviderContext } from '../../ftr_provider_context'; const DEFAULT_REQUEST = ` @@ -24,7 +25,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const retry = getService('retry'); const log = getService('log'); const browser = getService('browser'); - const PageObjects = getPageObjects(['common', 'console']); + const PageObjects = getPageObjects(['common', 'console', 'header']); const toasts = getService('toasts'); describe('console app', function describeIndexTests() { @@ -124,17 +125,20 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); describe('multiple requests output', () => { - const sendRequests = async () => { - await PageObjects.console.enterRequest('\n PUT test-index'); - await PageObjects.console.enterRequest('\n DELETE test-index'); + const sendMultipleRequests = async (requests: string[]) => { + await asyncForEach(requests, async (request) => { + await PageObjects.console.enterRequest(request); + }); await PageObjects.console.selectAllRequests(); await PageObjects.console.clickPlay(); }; + beforeEach(async () => { await PageObjects.console.clearTextArea(); }); + it('should contain comments starting with # symbol', async () => { - await sendRequests(); + await sendMultipleRequests(['\n PUT test-index', '\n DELETE test-index']); await retry.try(async () => { const response = await PageObjects.console.getResponse(); log.debug(response); @@ -142,13 +146,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(response).to.contain('# DELETE test-index 200 OK'); }); }); - it('should display status badges', async () => { - // This request should fail - await PageObjects.console.enterRequest('\n GET test-index'); - await sendRequests(); - await retry.waitFor('success badge', () => PageObjects.console.hasSuccessBadge()); - await retry.waitFor('warning badge', () => PageObjects.console.hasWarningBadge()); + it('should display status badges', async () => { + await sendMultipleRequests(['\n GET _search/test', '\n GET _search']); + await PageObjects.header.waitUntilLoadingHasFinished(); + expect(await PageObjects.console.hasWarningBadge()).to.be(true); + expect(await PageObjects.console.hasSuccessBadge()).to.be(true); }); }); }); diff --git a/test/functional/page_objects/console_page.ts b/test/functional/page_objects/console_page.ts index b12b731dac5b2..e8467ce714ff8 100644 --- a/test/functional/page_objects/console_page.ts +++ b/test/functional/page_objects/console_page.ts @@ -170,19 +170,19 @@ export class ConsolePageObject extends FtrService { await editor.pressKeys([selectionKey, 'a']); } - public async hasSuccessBadge(): Promise { + public async hasSuccessBadge() { try { const responseEditor = await this.testSubjects.find('response-editor'); - return Boolean(responseEditor.findByCssSelector('.ace_badge-success')); + return Boolean(await responseEditor.findByCssSelector('.ace_badge--success')); } catch (e) { return false; } } - public async hasWarningBadge(): Promise { + public async hasWarningBadge() { try { const responseEditor = await this.testSubjects.find('response-editor'); - return Boolean(responseEditor.findByCssSelector('.ace_badge-warning')); + return Boolean(await responseEditor.findByCssSelector('.ace_badge--warning')); } catch (e) { return false; } From eaaee4b203e24bc972ab53a1ed05b580c5c4a570 Mon Sep 17 00:00:00 2001 From: Muhammad Ibragimov Date: Thu, 26 May 2022 14:18:32 +0500 Subject: [PATCH 15/18] Fix types for editor session.update method --- .../models/legacy_core_editor/create_readonly.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/plugins/console/public/application/models/legacy_core_editor/create_readonly.ts b/src/plugins/console/public/application/models/legacy_core_editor/create_readonly.ts index 8b5af8e560519..7924b06e8b15f 100644 --- a/src/plugins/console/public/application/models/legacy_core_editor/create_readonly.ts +++ b/src/plugins/console/public/application/models/legacy_core_editor/create_readonly.ts @@ -27,7 +27,7 @@ export function createReadOnlyAceEditor(element: HTMLElement): CustomAceEditor { output.$blockScrolling = Infinity; output.resize = smartResize(output); - output.update = (val: string, mode?: string | Mode, cb?: () => void) => { + output.update = (val, mode, cb) => { if (typeof mode === 'function') { cb = mode as () => void; mode = void 0; @@ -36,7 +36,10 @@ export function createReadOnlyAceEditor(element: HTMLElement): CustomAceEditor { const session = output.getSession(); const currentMode = val ? mode || outputMode : 'ace/mode/text'; - session.setMode(currentMode as string); + // @ts-ignore + // ignore ts error here due to type definition mistake in brace for setMode(mode: string): void; + // this method accepts string or SyntaxMode which is an object. See https://github.com/ajaxorg/ace/blob/13dc911dbc0ea31ca343d5744b3f472767458fc3/ace.d.ts#L467 + session.setMode(currentMode); session.setValue(val); if (typeof cb === 'function') { setTimeout(cb); From 371ce42d50865b0ff75988af0260babf6d69bb83 Mon Sep 17 00:00:00 2001 From: Muhammad Ibragimov Date: Fri, 27 May 2022 09:33:59 +0500 Subject: [PATCH 16/18] Add tests for mapStatusCodeToBadge function --- .../mode/output_highlight_rules.test.ts | 55 +++++++++++++++++++ .../mode/output_highlight_rules.ts | 40 +++++++------- 2 files changed, 76 insertions(+), 19 deletions(-) create mode 100644 src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.test.ts diff --git a/src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.test.ts b/src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.test.ts new file mode 100644 index 0000000000000..cdbbd4bc7b178 --- /dev/null +++ b/src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.test.ts @@ -0,0 +1,55 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { mapStatusCodeToBadge } from './output_highlight_rules'; + +describe('mapStatusCodeToBadge', () => { + const testCases = [ + { + description: 'treats 100 as as default', + value: '# PUT test-index 100 Continue', + badge: 'badge.badge--default', + }, + { + description: 'treats 200 as success', + value: '# PUT test-index 200 OK', + badge: 'badge.badge--success', + }, + { + description: 'treats 301 as primary', + value: '# PUT test-index 301 Moved Permanently', + badge: 'badge.badge--primary', + }, + { + description: 'treats 400 as warning', + value: '# PUT test-index 404 Not Found', + badge: 'badge.badge--warning', + }, + { + description: 'treats 502 as danger', + value: '# PUT test-index 502 Bad Gateway', + badge: 'badge.badge--danger', + }, + { + description: 'treats unexpected numbers as danger', + value: '# PUT test-index 666 Demonic Invasion', + badge: 'badge.badge--danger', + }, + { + description: 'treats no numbers as undefined', + value: '# PUT test-index', + badge: undefined, + }, + ]; + + testCases.forEach(({ description, value, badge }) => { + test(description, () => { + expect(mapStatusCodeToBadge(value)).toBe(badge); + }); + }); +}); diff --git a/src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.ts b/src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.ts index 3c82100ef2e9d..925bcde746b85 100644 --- a/src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.ts +++ b/src/plugins/console/public/application/models/legacy_core_editor/mode/output_highlight_rules.ts @@ -12,6 +12,26 @@ import { addXJsonToRules } from '@kbn/ace'; const JsonHighlightRules = ace.acequire('ace/mode/json_highlight_rules').JsonHighlightRules; +export const mapStatusCodeToBadge = (value: string) => { + const regExpMatchArray = value.match(/\d+/); + if (regExpMatchArray) { + const status = parseInt(regExpMatchArray[0], 10); + if (status <= 199) { + return 'badge.badge--default'; + } + if (status <= 299) { + return 'badge.badge--success'; + } + if (status <= 399) { + return 'badge.badge--primary'; + } + if (status <= 499) { + return 'badge.badge--warning'; + } + return 'badge.badge--danger'; + } +}; + export class OutputJsonHighlightRules extends JsonHighlightRules { constructor() { super(); @@ -27,25 +47,7 @@ export class OutputJsonHighlightRules extends JsonHighlightRules { regex: /#(.*?)(?=\d+\s(?:[\sA-Za-z]+)|$)/, }, { - token(value: string) { - const regExpMatchArray = value.match(/\d+/); - if (regExpMatchArray) { - const status = parseInt(regExpMatchArray[0], 10); - if (status <= 199) { - return 'badge.badge--default'; - } - if (status <= 299) { - return 'badge.badge--success'; - } - if (status <= 399) { - return 'badge.badge--primary'; - } - if (status <= 499) { - return 'badge.badge--warning'; - } - return 'badge.badge--danger'; - } - }, + token: mapStatusCodeToBadge, regex: /(\d+\s[\sA-Za-z]+$)/, } ); From ad57319ef66412f6cc8bbf129f112cb1fb2a6912 Mon Sep 17 00:00:00 2001 From: Muhammad Ibragimov Date: Fri, 3 Jun 2022 16:31:23 +0500 Subject: [PATCH 17/18] Address comments --- src/plugins/console/public/styles/_app.scss | 32 ++++++++++----------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/src/plugins/console/public/styles/_app.scss b/src/plugins/console/public/styles/_app.scss index 86873305bfb20..75836d5940845 100644 --- a/src/plugins/console/public/styles/_app.scss +++ b/src/plugins/console/public/styles/_app.scss @@ -35,43 +35,41 @@ flex: 1 1 1px; .ace_badge { - font-size: 12px; - font-weight: 500; - line-height: 18px; - padding: 0 8px; + font-size: $euiFontSizeXS; + font-weight: $euiFontWeightMedium; + line-height: $euiLineHeight; + padding: 0 $euiSizeS; display: inline-block; text-decoration: none; - border-radius: 3px; - border: solid 1px transparent; + border-radius: $euiBorderRadius / 2; white-space: nowrap; vertical-align: middle; cursor: default; max-width: 100%; - text-align: left; &--success { - background-color: $euiColorSuccess; - color: chooseLightOrDarkText($euiColorSuccess); + background-color: $euiColorVis0_behindText; + color: chooseLightOrDarkText($euiColorVis0_behindText); } &--warning { - background-color: $euiColorWarning; - color: chooseLightOrDarkText($euiColorWarning); + background-color: $euiColorVis5_behindText; + color: chooseLightOrDarkText($euiColorVis5_behindText); } &--primary { - background-color: $euiColorPrimary; - color: chooseLightOrDarkText($euiColorPrimary); + background-color: $euiColorVis1_behindText; + color: chooseLightOrDarkText($euiColorVis1_behindText); } &--default { - background-color: $euiColorGhost; - color: chooseLightOrDarkText($euiColorGhost); + background-color: $euiColorLightShade; + color: chooseLightOrDarkText($euiColorLightShade); } &--danger { - background-color: $euiColorDanger; - color: chooseLightOrDarkText($euiColorDanger); + background-color: $euiColorVis9_behindText; + color: chooseLightOrDarkText($euiColorVis9_behindText); } } } From 49960438b12a66c4e4de762e64d2a66d268ad7a8 Mon Sep 17 00:00:00 2001 From: Muhammad Ibragimov Date: Mon, 6 Jun 2022 09:34:55 +0500 Subject: [PATCH 18/18] Change .ace-badge font family to $euiFontFamily --- src/plugins/console/public/styles/_app.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/console/public/styles/_app.scss b/src/plugins/console/public/styles/_app.scss index 75836d5940845..2490bb29f0fb7 100644 --- a/src/plugins/console/public/styles/_app.scss +++ b/src/plugins/console/public/styles/_app.scss @@ -35,6 +35,7 @@ flex: 1 1 1px; .ace_badge { + font-family: $euiFontFamily; font-size: $euiFontSizeXS; font-weight: $euiFontWeightMedium; line-height: $euiLineHeight;