[Tests] add smoke functional tests for "render" telemetries (#143522)

## Summary

[Tests] add smoke functional tests for "render" telemetries

This PR blocked by #143734 and #143552

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Marco Liberati <dej611@users.noreply.github.com>
This commit is contained in:
Alexey Antonov 2022-11-21 15:44:05 +03:00 committed by GitHub
parent 082e4aa713
commit 913527036e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 249 additions and 0 deletions

View file

@ -504,6 +504,16 @@ class BrowserService extends FtrService {
await this.driver.executeScript('return window.sessionStorage.clear();');
}
/**
* Get from the "local storage" by key
*
* @param {string} key
* @return {Promise<string>}
*/
public async getLocalStorageItem(key: string): Promise<string | null> {
return await this.driver.executeScript<string>(`return window.localStorage.getItem("${key}");`);
}
/**
* Closes the currently focused window. In most environments, after the window has been
* closed, it is necessary to explicitly switch to whatever window is now focused.

View file

@ -50,6 +50,7 @@ import { SavedQueryManagementComponentService } from './saved_query_management_c
import { KibanaSupertestProvider } from './supertest';
import { MenuToggleService } from './menu_toggle';
import { MonacoEditorService } from './monaco_editor';
import { UsageCollectionService } from './usage_collection';
export const services = {
...commonServiceProviders,
@ -90,4 +91,5 @@ export const services = {
monacoEditor: MonacoEditorService,
menuToggle: MenuToggleService,
retryOnStale: RetryOnStaleProvider,
usageCollection: UsageCollectionService,
};

View file

@ -47,4 +47,23 @@ export class RenderableService extends FtrService {
}
});
}
public async getRenderCount(count: number = 1): Promise<Record<string, number>> {
const map: Record<string, number> = {};
await this.waitForRender(count);
const renderedElements = await this.find.allByCssSelector(RENDER_COMPLETE_SELECTOR);
for (let i = 0; i < renderedElements.length; i++) {
const renderedElement = renderedElements[i];
const title = (await renderedElement.getAttribute('data-title')) || i.toString();
const renderingCount = Number(
(await renderedElement.getAttribute('data-rendering-count')) || '0'
);
map[title] = renderingCount;
}
return map;
}
}

View file

@ -0,0 +1,38 @@
/*
* 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 { FtrService } from '../ftr_provider_context';
const ANALYTICS_LOCAL_STORAGE_KEY = 'analytics';
export class UsageCollectionService extends FtrService {
private readonly browser = this.ctx.getService('browser');
public async getUICounterEvents(): Promise<
Array<{
key: string;
appName: string;
eventName: string;
type: string;
total: number;
}>
> {
try {
const rawValue = await this.browser.getLocalStorageItem(ANALYTICS_LOCAL_STORAGE_KEY);
if (rawValue) {
const { uiCounter } = JSON.parse(rawValue) ?? {};
return Object.values(uiCounter);
}
} catch (e) {
// nothing to be here
}
return [];
}
}

View file

@ -17,5 +17,6 @@ export default function visualize({ loadTestFile }: FtrProviderContext) {
loadTestFile(require.resolve('./precalculated_histogram'));
loadTestFile(require.resolve('./preserve_url'));
loadTestFile(require.resolve('./reporting'));
loadTestFile(require.resolve('./telemetry'));
});
}

View file

@ -0,0 +1,98 @@
/*
* 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; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import expect from '@kbn/expect';
import { FtrProviderContext } from '../../ftr_provider_context';
interface UiCounterEvent {
eventName: string;
total: number;
}
export default function ({ getService, getPageObjects }: FtrProviderContext) {
const PageObjects = getPageObjects(['common', 'dashboard', 'timePicker']);
const kibanaServer = getService('kibanaServer');
const esArchiver = getService('esArchiver');
const usageCollection = getService('usageCollection');
const renderable = getService('renderable');
const queryBar = getService('queryBar');
const retry = getService('retry');
describe('smoke telemetry tests', function () {
let uiCounterEvents: UiCounterEvent[] = [];
before(async function () {
await kibanaServer.savedObjects.cleanStandardList();
await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/logstash_functional');
await kibanaServer.importExport.load(
`x-pack/test/functional/fixtures/kbn_archiver/dashboard/with_by_value_visualizations`
);
await retry.try(async () => {
await PageObjects.common.navigateToApp('dashboard');
await PageObjects.dashboard.loadSavedDashboard('visualizations');
await PageObjects.timePicker.setDefaultAbsoluteRange();
await PageObjects.dashboard.waitForRenderComplete();
uiCounterEvents = await usageCollection.getUICounterEvents();
expect(uiCounterEvents.length).to.be.greaterThan(0);
});
});
after(async () => {
await kibanaServer.importExport.unload(
'x-pack/test/functional/fixtures/kbn_archiver/dashboard/with_by_value_visualizations'
);
await kibanaServer.savedObjects.cleanStandardList();
});
const checkTelemetry = (eventName: string) => {
const initialEvent = uiCounterEvents.find((e) => e.eventName === eventName);
expect(initialEvent).to.be.ok();
};
['legacy_metric', 'donut', 'timelion', 'area_stacked', 'table', 'heatmap'].forEach((vis) => {
it(`should trigger render event for "agg based" ${vis} visualization`, async () =>
checkTelemetry(`render_agg_based_${vis}`));
});
['vega', 'tsvb_top_n', 'lens_vis_dashboard'].forEach((vis) => {
it(`should trigger render event for ${vis} visualization`, async () =>
checkTelemetry(`render_${vis}`));
});
['vertical_bar_stacked', 'dimension_date_histogram', 'dimension_count'].forEach((i) => {
it(`should correctly trigger "render_lens${i}" lens event`, async () =>
checkTelemetry(`render_lens_${i}`));
});
describe('should render visualization once', async () => {
let initialRenderCountMap: Record<string, number> = {};
let afterRefreshRenderCountMap: Record<string, number> = {};
before(async function () {
const sharedItemsCount = Number(await PageObjects.dashboard.getSharedItemsCount());
initialRenderCountMap = await renderable.getRenderCount(sharedItemsCount);
await queryBar.clickQuerySubmitButton();
await PageObjects.dashboard.waitForRenderComplete();
afterRefreshRenderCountMap = await renderable.getRenderCount(sharedItemsCount);
});
['Lens', 'TSVB', 'Vega', 'Table', 'Timelion', 'Pie', 'Metric', 'Heatmap', 'Area'].forEach(
(key) => {
it(`should correctly render ${key} visualization once`, async () =>
expect(afterRefreshRenderCountMap[key]).to.be(initialRenderCountMap[key] + 1));
}
);
});
});
}

File diff suppressed because one or more lines are too long