Skip to content

Commit

Permalink
Merge branch 'main' into 135265/optimize-duplicate-last-value-functions
Browse files Browse the repository at this point in the history
  • Loading branch information
kibanamachine authored Sep 26, 2022
2 parents 845822f + adffaa4 commit a8e560d
Show file tree
Hide file tree
Showing 14 changed files with 641 additions and 95 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -1265,7 +1265,7 @@
"babel-plugin-require-context-hook": "^1.0.0",
"babel-plugin-styled-components": "^2.0.7",
"babel-plugin-transform-react-remove-prop-types": "^0.4.24",
"backport": "^8.9.2",
"backport": "^8.9.4",
"callsites": "^3.1.0",
"chance": "1.0.18",
"chokidar": "^3.5.3",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
*/

import fetch from 'node-fetch';
import Semver from 'semver';
import { Logger } from '../../utils/create_logger';

export class ApmSynthtraceKibanaClient {
Expand Down Expand Up @@ -53,31 +52,33 @@ export class ApmSynthtraceKibanaClient {
return kibanaUrl;
});
}
async fetchLatestApmPackageVersion(currentKibanaVersion: string) {
const url = `https://epr-snapshot.elastic.co/search?package=apm&prerelease=true&all=true&kibana.version=${currentKibanaVersion}`;
const response = await fetch(url, { method: 'GET' });
const json = (await response.json()) as Array<{ version: string }>;
const packageVersions = (json ?? []).map((item) => item.version).sort(Semver.rcompare);
const validPackageVersions = packageVersions.filter((v) => Semver.valid(v));
const bestMatch = validPackageVersions[0];
if (!bestMatch) {
throw new Error(
`None of the available APM package versions matches the current Kibana version (${currentKibanaVersion}). The latest available version is ${packageVersions[0]}. This can happen if the Kibana version was recently bumped, and no matching APM package was released. Reach out to the fleet team if this persists.`
);
}
return bestMatch;

async fetchLatestApmPackageVersion(
kibanaUrl: string,
version: string,
username: string,
password: string
) {
const url = `${kibanaUrl}/api/fleet/epm/packages/apm`;
const response = await fetch(url, {
method: 'GET',
headers: kibanaHeaders(username, password),
});
const json = (await response.json()) as { item: { latestVersion: string } };
const { latestVersion } = json.item;
return latestVersion;
}

async installApmPackage(kibanaUrl: string, version: string, username: string, password: string) {
const packageVersion = await this.fetchLatestApmPackageVersion(version);
const packageVersion = await this.fetchLatestApmPackageVersion(
kibanaUrl,
version,
username,
password
);
const response = await fetch(`${kibanaUrl}/api/fleet/epm/packages/apm/${packageVersion}`, {
method: 'POST',
headers: {
Authorization: 'Basic ' + Buffer.from(username + ':' + password).toString('base64'),
Accept: 'application/json',
'Content-Type': 'application/json',
'kbn-xsrf': 'kibana',
},
headers: kibanaHeaders(username, password),
body: '{"force":true}',
});

Expand All @@ -93,3 +94,12 @@ export class ApmSynthtraceKibanaClient {
} else this.logger.error(responseJson);
}
}

function kibanaHeaders(username: string, password: string) {
return {
Authorization: 'Basic ' + Buffer.from(username + ':' + password).toString('base64'),
Accept: 'application/json',
'Content-Type': 'application/json',
'kbn-xsrf': 'kibana',
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ export class ConsoleMenu extends Component<Props, State> {
const items = [
<EuiContextMenuItem
key="Copy as cURL"
data-test-subj="consoleMenuCopyAsCurl"
id="ConCopyAsCurl"
disabled={!window.navigator?.clipboard}
onClick={() => {
Expand Down Expand Up @@ -174,7 +175,7 @@ export class ConsoleMenu extends Component<Props, State> {
panelPaddingSize="none"
anchorPosition="downLeft"
>
<EuiContextMenuPanel items={items} />
<EuiContextMenuPanel items={items} data-test-subj="consoleMenu" />
</EuiPopover>
</span>
);
Expand Down
104 changes: 104 additions & 0 deletions test/functional/apps/console/_context_menu.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*
* 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 expect from '@kbn/expect';
import { FtrProviderContext } from '../../ftr_provider_context';

export default function ({ getService, getPageObjects }: FtrProviderContext) {
const log = getService('log');
const retry = getService('retry');
const PageObjects = getPageObjects(['common', 'console']);
const browser = getService('browser');
const toasts = getService('toasts');

describe('console context menu', function testContextMenu() {
before(async () => {
await PageObjects.common.navigateToApp('console');
// Ensure that the text area can be interacted with
await PageObjects.console.closeHelpIfExists();
await PageObjects.console.clearTextArea();
});

it('should open context menu', async () => {
expect(await PageObjects.console.isContextMenuOpen()).to.be(false);
await PageObjects.console.enterRequest();
await PageObjects.console.clickContextMenu();
expect(PageObjects.console.isContextMenuOpen()).to.be.eql(true);
});

it('should have options to copy as curl, open documentation, and auto indent', async () => {
await PageObjects.console.clickContextMenu();
expect(PageObjects.console.isContextMenuOpen()).to.be.eql(true);
expect(PageObjects.console.isCopyAsCurlButtonVisible()).to.be.eql(true);
expect(PageObjects.console.isOpenDocumentationButtonVisible()).to.be.eql(true);
expect(PageObjects.console.isAutoIndentButtonVisible()).to.be.eql(true);
});

it('should copy as curl and show toast when copy as curl button is clicked', async () => {
await PageObjects.console.clickContextMenu();
await PageObjects.console.clickCopyAsCurlButton();

const resultToast = await toasts.getToastElement(1);
const toastText = await resultToast.getVisibleText();

if (toastText.includes('Write permission denied')) {
log.debug('Write permission denied, skipping test');
return;
}

expect(toastText).to.be('Request copied as cURL');

const canReadClipboard = await browser.checkBrowserPermission('clipboard-read');
if (canReadClipboard) {
const clipboardText = await browser.getClipboardValue();
expect(clipboardText).to.contain('curl -XGET');
}
});

it('should open documentation when open documentation button is clicked', async () => {
await PageObjects.console.clickContextMenu();
await PageObjects.console.clickOpenDocumentationButton();

await retry.tryForTime(10000, async () => {
await browser.switchTab(1);
});

// Retry until the documentation is loaded
await retry.try(async () => {
const url = await browser.getCurrentUrl();
expect(url).to.contain('search-search.html');
});

// Close the documentation tab
await browser.closeCurrentWindow();
await browser.switchTab(0);
});

it('should auto indent when auto indent button is clicked', async () => {
await PageObjects.console.clearTextArea();
await PageObjects.console.enterRequest('GET _search\n{"query": {"match_all": {}}}');
await PageObjects.console.clickContextMenu();
await PageObjects.console.clickAutoIndentButton();
// Retry until the request is auto indented
await retry.try(async () => {
const request = await PageObjects.console.getRequest();
expect(request).to.be.eql('GET _search\n{\n "query": {\n "match_all": {}\n }\n}');
});
});

it('should condense when auto indent button is clicked again', async () => {
await PageObjects.console.clickContextMenu();
await PageObjects.console.clickAutoIndentButton();
// Retry until the request is condensed
await retry.try(async () => {
const request = await PageObjects.console.getRequest();
expect(request).to.be.eql('GET _search\n{"query":{"match_all":{}}}');
});
});
});
}
1 change: 1 addition & 0 deletions test/functional/apps/console/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export default function ({ getService, loadTestFile }) {
loadTestFile(require.resolve('./_variables'));
loadTestFile(require.resolve('./_xjson'));
loadTestFile(require.resolve('./_misc_console_behavior'));
loadTestFile(require.resolve('./_context_menu'));
}
});
}
36 changes: 36 additions & 0 deletions test/functional/page_objects/console_page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -368,4 +368,40 @@ export class ConsolePageObject extends FtrService {
const textArea = await this.testSubjects.find('console-textarea');
await textArea.pressKeys([Key[process.platform === 'darwin' ? 'COMMAND' : 'CONTROL'], '/']);
}

public async clickContextMenu() {
const contextMenu = await this.testSubjects.find('toggleConsoleMenu');
await contextMenu.click();
}

public async isContextMenuOpen() {
return await this.testSubjects.exists('consoleMenu');
}

public async isCopyAsCurlButtonVisible() {
return await this.testSubjects.exists('consoleMenuCopyAsCurl');
}

public async isOpenDocumentationButtonVisible() {
return await this.testSubjects.exists('consoleMenuOpenDocs');
}

public async isAutoIndentButtonVisible() {
return await this.testSubjects.exists('consoleMenuAutoIndent');
}

public async clickCopyAsCurlButton() {
const button = await this.testSubjects.find('consoleMenuCopyAsCurl');
await button.click();
}

public async clickOpenDocumentationButton() {
const button = await this.testSubjects.find('consoleMenuOpenDocs');
await button.click();
}

public async clickAutoIndentButton() {
const button = await this.testSubjects.find('consoleMenuAutoIndent');
await button.click();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -228,9 +228,26 @@ export const SpikeAnalysisGroupsTable: FC<SpikeAnalysisTableProps> = ({
{
'data-test-subj': 'aiopsSpikeAnalysisGroupsTableColumnGroup',
field: 'group',
name: i18n.translate('xpack.aiops.explainLogRateSpikes.spikeAnalysisTableGroups.groupLabel', {
defaultMessage: 'Group',
}),
name: (
<EuiToolTip
position="top"
content={i18n.translate(
'xpack.aiops.explainLogRateSpikes.spikeAnalysisTableGroups.groupColumnTooltip',
{
defaultMessage:
'Displays field values unique to the group. Expand row to see all values.',
}
)}
>
<>
<FormattedMessage
id="xpack.aiops.explainLogRateSpikes.spikeAnalysisTableGroups.groupLabel"
defaultMessage="Group"
/>
<EuiIcon size="s" color="subdued" type="questionInCircle" className="eui-alignTop" />
</>
</EuiToolTip>
),
render: (_, { group, repeatedValues }) => {
const valuesBadges = [];
for (const fieldName in group) {
Expand Down Expand Up @@ -287,7 +304,7 @@ export const SpikeAnalysisGroupsTable: FC<SpikeAnalysisTableProps> = ({
'xpack.aiops.explainLogRateSpikes.spikeAnalysisTableGroups.logRateColumnTooltip',
{
defaultMessage:
'A visual representation of the impact of the field on the message rate difference',
'A visual representation of the impact of the group on the message rate difference',
}
)}
>
Expand Down Expand Up @@ -361,9 +378,9 @@ export const SpikeAnalysisGroupsTable: FC<SpikeAnalysisTableProps> = ({
<EuiToolTip
position="top"
content={i18n.translate(
'xpack.aiops.explainLogRateSpikes.spikeAnalysisTable.impactLabelColumnTooltip',
'xpack.aiops.explainLogRateSpikes.spikeAnalysisTableGroups.impactLabelColumnTooltip',
{
defaultMessage: 'The level of impact of the field on the message rate difference',
defaultMessage: 'The level of impact of the group on the message rate difference',
}
)}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ export const UploadFile = <Kind extends string = string>({
return () => subs.forEach((sub) => sub.unsubscribe());
}, [uploadState, onDone, onError]);

useEffect(() => uploadState.dispose, [uploadState]);

return (
<context.Provider value={uploadState}>
<Component
Expand Down
Loading

0 comments on commit a8e560d

Please sign in to comment.