[ML] Data Frame Analytics: Fix color assertion with risk of percentage being rounded to 0. (#95797)
- Fix color assertion with risk of percentage being rounded to 0. - Better naming of attributes of expected values. - Adds assertions to use the sample size dropdown and randomize query switch.
This commit is contained in:
parent
d10935cf07
commit
d9a475258b
|
@ -331,6 +331,7 @@ export const ScatterplotMatrix: FC<ScatterplotMatrixProps> = ({
|
||||||
fullWidth
|
fullWidth
|
||||||
>
|
>
|
||||||
<EuiSelect
|
<EuiSelect
|
||||||
|
data-test-subj="mlScatterplotMatrixSampleSizeSelect"
|
||||||
compressed
|
compressed
|
||||||
options={sampleSizeOptions}
|
options={sampleSizeOptions}
|
||||||
value={fetchSize}
|
value={fetchSize}
|
||||||
|
@ -355,6 +356,7 @@ export const ScatterplotMatrix: FC<ScatterplotMatrixProps> = ({
|
||||||
fullWidth
|
fullWidth
|
||||||
>
|
>
|
||||||
<EuiSwitch
|
<EuiSwitch
|
||||||
|
data-test-subj="mlScatterplotMatrixRandomizeQuerySwitch"
|
||||||
name="mlScatterplotMatrixRandomizeQuery"
|
name="mlScatterplotMatrixRandomizeQuery"
|
||||||
label={randomizeQuery ? TOGGLE_ON : TOGGLE_OFF}
|
label={randomizeQuery ? TOGGLE_ON : TOGGLE_OFF}
|
||||||
checked={randomizeQuery}
|
checked={randomizeQuery}
|
||||||
|
|
|
@ -12,8 +12,7 @@ export default function ({ getService }: FtrProviderContext) {
|
||||||
const ml = getService('ml');
|
const ml = getService('ml');
|
||||||
const editedDescription = 'Edited description';
|
const editedDescription = 'Edited description';
|
||||||
|
|
||||||
// FLAKY: https://github.com/elastic/kibana/issues/91450
|
describe('classification creation', function () {
|
||||||
describe.skip('classification creation', function () {
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
await esArchiver.loadIfNeeded('ml/bm_classification');
|
await esArchiver.loadIfNeeded('ml/bm_classification');
|
||||||
await ml.testResources.createIndexPatternIfNeeded('ft_bank_marketing', '@timestamp');
|
await ml.testResources.createIndexPatternIfNeeded('ft_bank_marketing', '@timestamp');
|
||||||
|
@ -44,18 +43,18 @@ export default function ({ getService }: FtrProviderContext) {
|
||||||
expected: {
|
expected: {
|
||||||
rocCurveColorState: [
|
rocCurveColorState: [
|
||||||
// tick/grid/axis
|
// tick/grid/axis
|
||||||
{ key: '#DDDDDD', value: 50 },
|
{ color: '#DDDDDD', percentage: 50 },
|
||||||
// line
|
// line
|
||||||
{ key: '#98A2B3', value: 30 },
|
{ color: '#98A2B3', percentage: 30 },
|
||||||
],
|
],
|
||||||
scatterplotMatrixColorStats: [
|
scatterplotMatrixColorStats: [
|
||||||
// marker colors
|
// marker colors
|
||||||
{ key: '#7FC6B3', value: 1 },
|
{ color: '#7FC6B3', percentage: 1 },
|
||||||
{ key: '#88ADD0', value: 0.03 },
|
{ color: '#88ADD0', percentage: 0.03 },
|
||||||
// tick/grid/axis
|
// tick/grid/axis
|
||||||
{ key: '#DDDDDD', value: 8 },
|
{ color: '#DDDDDD', percentage: 8 },
|
||||||
{ key: '#D3DAE6', value: 8 },
|
{ color: '#D3DAE6', percentage: 8 },
|
||||||
{ key: '#F5F7FA', value: 20 },
|
{ color: '#F5F7FA', percentage: 15 },
|
||||||
],
|
],
|
||||||
row: {
|
row: {
|
||||||
type: 'classification',
|
type: 'classification',
|
||||||
|
@ -78,6 +77,10 @@ export default function ({ getService }: FtrProviderContext) {
|
||||||
await ml.navigation.navigateToDataFrameAnalytics();
|
await ml.navigation.navigateToDataFrameAnalytics();
|
||||||
|
|
||||||
await ml.testExecution.logTestStep('loads the source selection modal');
|
await ml.testExecution.logTestStep('loads the source selection modal');
|
||||||
|
|
||||||
|
// Disable anti-aliasing to stabilize canvas image rendering assertions
|
||||||
|
await ml.commonUI.disableAntiAliasing();
|
||||||
|
|
||||||
await ml.dataFrameAnalytics.startAnalyticsCreation();
|
await ml.dataFrameAnalytics.startAnalyticsCreation();
|
||||||
|
|
||||||
await ml.testExecution.logTestStep(
|
await ml.testExecution.logTestStep(
|
||||||
|
@ -106,6 +109,16 @@ export default function ({ getService }: FtrProviderContext) {
|
||||||
await ml.testExecution.logTestStep('displays the include fields selection');
|
await ml.testExecution.logTestStep('displays the include fields selection');
|
||||||
await ml.dataFrameAnalyticsCreation.assertIncludeFieldsSelectionExists();
|
await ml.dataFrameAnalyticsCreation.assertIncludeFieldsSelectionExists();
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep(
|
||||||
|
'sets the sample size to 10000 for the scatterplot matrix'
|
||||||
|
);
|
||||||
|
await ml.dataFrameAnalyticsCreation.setScatterplotMatrixSampleSizeSelectValue('10000');
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep(
|
||||||
|
'sets the randomize query switch to true for the scatterplot matrix'
|
||||||
|
);
|
||||||
|
await ml.dataFrameAnalyticsCreation.setScatterplotMatrixRandomizeQueryCheckState(true);
|
||||||
|
|
||||||
await ml.testExecution.logTestStep('displays the scatterplot matrix');
|
await ml.testExecution.logTestStep('displays the scatterplot matrix');
|
||||||
await ml.dataFrameAnalyticsCreation.assertScatterplotMatrix(
|
await ml.dataFrameAnalyticsCreation.assertScatterplotMatrix(
|
||||||
testData.expected.scatterplotMatrixColorStats
|
testData.expected.scatterplotMatrixColorStats
|
||||||
|
@ -237,6 +250,12 @@ export default function ({ getService }: FtrProviderContext) {
|
||||||
await ml.testExecution.logTestStep('displays the results view for created job');
|
await ml.testExecution.logTestStep('displays the results view for created job');
|
||||||
await ml.dataFrameAnalyticsTable.openResultsView(testData.jobId);
|
await ml.dataFrameAnalyticsTable.openResultsView(testData.jobId);
|
||||||
await ml.dataFrameAnalyticsResults.assertClassificationEvaluatePanelElementsExists();
|
await ml.dataFrameAnalyticsResults.assertClassificationEvaluatePanelElementsExists();
|
||||||
|
await ml.dataFrameAnalyticsResults.assertClassificationTablePanelExists();
|
||||||
|
await ml.dataFrameAnalyticsResults.assertResultsTableExists();
|
||||||
|
await ml.dataFrameAnalyticsResults.assertResultsTableTrainingFiltersExist();
|
||||||
|
await ml.dataFrameAnalyticsResults.assertResultsTableNotEmpty();
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('displays the ROC curve chart');
|
||||||
await ml.commonUI.assertColorsInCanvasElement(
|
await ml.commonUI.assertColorsInCanvasElement(
|
||||||
'mlDFAnalyticsClassificationExplorationRocCurveChart',
|
'mlDFAnalyticsClassificationExplorationRocCurveChart',
|
||||||
testData.expected.rocCurveColorState,
|
testData.expected.rocCurveColorState,
|
||||||
|
@ -247,13 +266,23 @@ export default function ({ getService }: FtrProviderContext) {
|
||||||
// since the returned colors vary quite a bit on each run.
|
// since the returned colors vary quite a bit on each run.
|
||||||
20
|
20
|
||||||
);
|
);
|
||||||
await ml.dataFrameAnalyticsResults.assertClassificationTablePanelExists();
|
|
||||||
await ml.dataFrameAnalyticsResults.assertResultsTableExists();
|
await ml.testExecution.logTestStep(
|
||||||
await ml.dataFrameAnalyticsResults.assertResultsTableTrainingFiltersExist();
|
'sets the sample size to 10000 for the scatterplot matrix'
|
||||||
await ml.dataFrameAnalyticsResults.assertResultsTableNotEmpty();
|
);
|
||||||
|
await ml.dataFrameAnalyticsResults.setScatterplotMatrixSampleSizeSelectValue('10000');
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep(
|
||||||
|
'sets the randomize query switch to true for the scatterplot matrix'
|
||||||
|
);
|
||||||
|
await ml.dataFrameAnalyticsResults.setScatterplotMatrixRandomizeQueryCheckState(true);
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('displays the scatterplot matrix');
|
||||||
await ml.dataFrameAnalyticsResults.assertScatterplotMatrix(
|
await ml.dataFrameAnalyticsResults.assertScatterplotMatrix(
|
||||||
testData.expected.scatterplotMatrixColorStats
|
testData.expected.scatterplotMatrixColorStats
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await ml.commonUI.resetAntiAliasing();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('displays the analytics job in the map view', async () => {
|
it('displays the analytics job in the map view', async () => {
|
||||||
|
|
|
@ -52,19 +52,19 @@ export default function ({ getService }: FtrProviderContext) {
|
||||||
],
|
],
|
||||||
scatterplotMatrixColorsWizard: [
|
scatterplotMatrixColorsWizard: [
|
||||||
// markers
|
// markers
|
||||||
{ key: '#52B398', value: 25 },
|
{ color: '#52B398', percentage: 15 },
|
||||||
// grey boilerplate
|
// grey boilerplate
|
||||||
{ key: '#6A717D', value: 30 },
|
{ color: '#6A717D', percentage: 33 },
|
||||||
],
|
],
|
||||||
scatterplotMatrixColorStatsResults: [
|
scatterplotMatrixColorStatsResults: [
|
||||||
// red markers
|
// red markers
|
||||||
{ key: '#D98071', value: 1 },
|
{ color: '#D98071', percentage: 1 },
|
||||||
// tick/grid/axis, grey markers
|
// tick/grid/axis, grey markers
|
||||||
{ key: '#6A717D', value: 30 },
|
{ color: '#6A717D', percentage: 33 },
|
||||||
{ key: '#D3DAE6', value: 8 },
|
{ color: '#D3DAE6', percentage: 8 },
|
||||||
{ key: '#98A1B3', value: 25 },
|
{ color: '#98A1B3', percentage: 12 },
|
||||||
// anti-aliasing
|
// anti-aliasing
|
||||||
{ key: '#F5F7FA', value: 27 },
|
{ color: '#F5F7FA', percentage: 30 },
|
||||||
],
|
],
|
||||||
row: {
|
row: {
|
||||||
type: 'outlier_detection',
|
type: 'outlier_detection',
|
||||||
|
@ -126,6 +126,16 @@ export default function ({ getService }: FtrProviderContext) {
|
||||||
await ml.testExecution.logTestStep('displays the include fields selection');
|
await ml.testExecution.logTestStep('displays the include fields selection');
|
||||||
await ml.dataFrameAnalyticsCreation.assertIncludeFieldsSelectionExists();
|
await ml.dataFrameAnalyticsCreation.assertIncludeFieldsSelectionExists();
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep(
|
||||||
|
'sets the sample size to 10000 for the scatterplot matrix'
|
||||||
|
);
|
||||||
|
await ml.dataFrameAnalyticsCreation.setScatterplotMatrixSampleSizeSelectValue('10000');
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep(
|
||||||
|
'sets the randomize query switch to true for the scatterplot matrix'
|
||||||
|
);
|
||||||
|
await ml.dataFrameAnalyticsCreation.setScatterplotMatrixRandomizeQueryCheckState(true);
|
||||||
|
|
||||||
await ml.testExecution.logTestStep('displays the scatterplot matrix');
|
await ml.testExecution.logTestStep('displays the scatterplot matrix');
|
||||||
await ml.dataFrameAnalyticsCreation.assertScatterplotMatrix(
|
await ml.dataFrameAnalyticsCreation.assertScatterplotMatrix(
|
||||||
testData.expected.scatterplotMatrixColorsWizard
|
testData.expected.scatterplotMatrixColorsWizard
|
||||||
|
@ -255,9 +265,23 @@ export default function ({ getService }: FtrProviderContext) {
|
||||||
await ml.dataFrameAnalyticsResults.assertResultsTableExists();
|
await ml.dataFrameAnalyticsResults.assertResultsTableExists();
|
||||||
await ml.dataFrameAnalyticsResults.assertResultsTableNotEmpty();
|
await ml.dataFrameAnalyticsResults.assertResultsTableNotEmpty();
|
||||||
await ml.dataFrameAnalyticsResults.assertFeatureInfluenceCellNotEmpty();
|
await ml.dataFrameAnalyticsResults.assertFeatureInfluenceCellNotEmpty();
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep(
|
||||||
|
'sets the sample size to 10000 for the scatterplot matrix'
|
||||||
|
);
|
||||||
|
await ml.dataFrameAnalyticsResults.setScatterplotMatrixSampleSizeSelectValue('10000');
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep(
|
||||||
|
'sets the randomize query switch to true for the scatterplot matrix'
|
||||||
|
);
|
||||||
|
await ml.dataFrameAnalyticsResults.setScatterplotMatrixRandomizeQueryCheckState(true);
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('displays the scatterplot matrix');
|
||||||
await ml.dataFrameAnalyticsResults.assertScatterplotMatrix(
|
await ml.dataFrameAnalyticsResults.assertScatterplotMatrix(
|
||||||
testData.expected.scatterplotMatrixColorStatsResults
|
testData.expected.scatterplotMatrixColorStatsResults
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await ml.commonUI.resetAntiAliasing();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('displays the analytics job in the map view', async () => {
|
it('displays the analytics job in the map view', async () => {
|
||||||
|
|
|
@ -42,12 +42,12 @@ export default function ({ getService }: FtrProviderContext) {
|
||||||
expected: {
|
expected: {
|
||||||
scatterplotMatrixColorStats: [
|
scatterplotMatrixColorStats: [
|
||||||
// some marker colors of the continuous color scale
|
// some marker colors of the continuous color scale
|
||||||
{ key: '#61AFA3', value: 2 },
|
{ color: '#61AFA3', percentage: 2 },
|
||||||
{ key: '#D1E5E0', value: 2 },
|
{ color: '#D1E5E0', percentage: 2 },
|
||||||
// tick/grid/axis
|
// tick/grid/axis
|
||||||
{ key: '#6A717D', value: 10 },
|
{ color: '#6A717D', percentage: 10 },
|
||||||
{ key: '#F5F7FA', value: 12 },
|
{ color: '#F5F7FA', percentage: 10 },
|
||||||
{ key: '#D3DAE6', value: 3 },
|
{ color: '#D3DAE6', percentage: 3 },
|
||||||
],
|
],
|
||||||
row: {
|
row: {
|
||||||
type: 'regression',
|
type: 'regression',
|
||||||
|
@ -71,6 +71,10 @@ export default function ({ getService }: FtrProviderContext) {
|
||||||
await ml.navigation.navigateToDataFrameAnalytics();
|
await ml.navigation.navigateToDataFrameAnalytics();
|
||||||
|
|
||||||
await ml.testExecution.logTestStep('loads the source selection modal');
|
await ml.testExecution.logTestStep('loads the source selection modal');
|
||||||
|
|
||||||
|
// Disable anti-aliasing to stabilize canvas image rendering assertions
|
||||||
|
await ml.commonUI.disableAntiAliasing();
|
||||||
|
|
||||||
await ml.dataFrameAnalytics.startAnalyticsCreation();
|
await ml.dataFrameAnalytics.startAnalyticsCreation();
|
||||||
|
|
||||||
await ml.testExecution.logTestStep(
|
await ml.testExecution.logTestStep(
|
||||||
|
@ -99,6 +103,16 @@ export default function ({ getService }: FtrProviderContext) {
|
||||||
await ml.testExecution.logTestStep('displays the include fields selection');
|
await ml.testExecution.logTestStep('displays the include fields selection');
|
||||||
await ml.dataFrameAnalyticsCreation.assertIncludeFieldsSelectionExists();
|
await ml.dataFrameAnalyticsCreation.assertIncludeFieldsSelectionExists();
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep(
|
||||||
|
'sets the sample size to 10000 for the scatterplot matrix'
|
||||||
|
);
|
||||||
|
await ml.dataFrameAnalyticsCreation.setScatterplotMatrixSampleSizeSelectValue('10000');
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep(
|
||||||
|
'sets the randomize query switch to true for the scatterplot matrix'
|
||||||
|
);
|
||||||
|
await ml.dataFrameAnalyticsCreation.setScatterplotMatrixRandomizeQueryCheckState(true);
|
||||||
|
|
||||||
await ml.testExecution.logTestStep('displays the scatterplot matrix');
|
await ml.testExecution.logTestStep('displays the scatterplot matrix');
|
||||||
await ml.dataFrameAnalyticsCreation.assertScatterplotMatrix(
|
await ml.dataFrameAnalyticsCreation.assertScatterplotMatrix(
|
||||||
testData.expected.scatterplotMatrixColorStats
|
testData.expected.scatterplotMatrixColorStats
|
||||||
|
@ -229,9 +243,23 @@ export default function ({ getService }: FtrProviderContext) {
|
||||||
await ml.dataFrameAnalyticsResults.assertResultsTableExists();
|
await ml.dataFrameAnalyticsResults.assertResultsTableExists();
|
||||||
await ml.dataFrameAnalyticsResults.assertResultsTableTrainingFiltersExist();
|
await ml.dataFrameAnalyticsResults.assertResultsTableTrainingFiltersExist();
|
||||||
await ml.dataFrameAnalyticsResults.assertResultsTableNotEmpty();
|
await ml.dataFrameAnalyticsResults.assertResultsTableNotEmpty();
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep(
|
||||||
|
'sets the sample size to 10000 for the scatterplot matrix'
|
||||||
|
);
|
||||||
|
await ml.dataFrameAnalyticsResults.setScatterplotMatrixSampleSizeSelectValue('10000');
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep(
|
||||||
|
'sets the randomize query switch to true for the scatterplot matrix'
|
||||||
|
);
|
||||||
|
await ml.dataFrameAnalyticsResults.setScatterplotMatrixRandomizeQueryCheckState(true);
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('displays the scatterplot matrix');
|
||||||
await ml.dataFrameAnalyticsResults.assertScatterplotMatrix(
|
await ml.dataFrameAnalyticsResults.assertScatterplotMatrix(
|
||||||
testData.expected.scatterplotMatrixColorStats
|
testData.expected.scatterplotMatrixColorStats
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await ml.commonUI.resetAntiAliasing();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('displays the analytics job in the map view', async () => {
|
it('displays the analytics job in the map view', async () => {
|
||||||
|
|
|
@ -161,8 +161,8 @@ export default function ({ getService }: FtrProviderContext) {
|
||||||
id: 'currency',
|
id: 'currency',
|
||||||
legend: '1 category',
|
legend: '1 category',
|
||||||
colorStats: [
|
colorStats: [
|
||||||
{ key: '#000000', value: 10 },
|
{ color: '#000000', percentage: 10 },
|
||||||
{ key: '#54B399', value: 90 },
|
{ color: '#54B399', percentage: 90 },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -177,8 +177,8 @@ export default function ({ getService }: FtrProviderContext) {
|
||||||
id: 'customer_gender',
|
id: 'customer_gender',
|
||||||
legend: '2 categories',
|
legend: '2 categories',
|
||||||
colorStats: [
|
colorStats: [
|
||||||
{ key: '#000000', value: 15 },
|
{ color: '#000000', percentage: 15 },
|
||||||
{ key: '#54B399', value: 85 },
|
{ color: '#54B399', percentage: 85 },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -186,8 +186,8 @@ export default function ({ getService }: FtrProviderContext) {
|
||||||
id: 'customer_id',
|
id: 'customer_id',
|
||||||
legend: 'top 20 of 46 categories',
|
legend: 'top 20 of 46 categories',
|
||||||
colorStats: [
|
colorStats: [
|
||||||
{ key: '#54B399', value: 35 },
|
{ color: '#54B399', percentage: 35 },
|
||||||
{ key: '#000000', value: 60 },
|
{ color: '#000000', percentage: 60 },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{ chartAvailable: false, id: 'customer_last_name', legend: 'Chart not supported.' },
|
{ chartAvailable: false, id: 'customer_last_name', legend: 'Chart not supported.' },
|
||||||
|
@ -196,8 +196,8 @@ export default function ({ getService }: FtrProviderContext) {
|
||||||
id: 'customer_phone',
|
id: 'customer_phone',
|
||||||
legend: '1 category',
|
legend: '1 category',
|
||||||
colorStats: [
|
colorStats: [
|
||||||
{ key: '#000000', value: 10 },
|
{ color: '#000000', percentage: 10 },
|
||||||
{ key: '#54B399', value: 90 },
|
{ color: '#54B399', percentage: 90 },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -205,8 +205,8 @@ export default function ({ getService }: FtrProviderContext) {
|
||||||
id: 'day_of_week',
|
id: 'day_of_week',
|
||||||
legend: '7 categories',
|
legend: '7 categories',
|
||||||
colorStats: [
|
colorStats: [
|
||||||
{ key: '#000000', value: 20 },
|
{ color: '#000000', percentage: 20 },
|
||||||
{ key: '#54B399', value: 75 },
|
{ color: '#54B399', percentage: 75 },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -8,6 +8,9 @@
|
||||||
import { TRANSFORM_STATE } from '../../../../plugins/transform/common/constants';
|
import { TRANSFORM_STATE } from '../../../../plugins/transform/common/constants';
|
||||||
|
|
||||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||||
|
|
||||||
|
import type { HistogramCharts } from '../../services/transform/wizard';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
GroupByEntry,
|
GroupByEntry,
|
||||||
isLatestTransformTestData,
|
isLatestTransformTestData,
|
||||||
|
@ -44,22 +47,22 @@ export default function ({ getService }: FtrProviderContext) {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Only testing that histogram charts are available for runtime fields here
|
// Only testing that histogram charts are available for runtime fields here
|
||||||
const histogramCharts = [
|
const histogramCharts: HistogramCharts = [
|
||||||
{
|
{
|
||||||
chartAvailable: true,
|
chartAvailable: true,
|
||||||
id: 'rt_airline_lower',
|
id: 'rt_airline_lower',
|
||||||
legend: '19 categories',
|
legend: '19 categories',
|
||||||
colorStats: [
|
colorStats: [
|
||||||
{ key: '#000000', value: 48 },
|
{ color: '#000000', percentage: 48 },
|
||||||
{ key: '#54B399', value: 41 },
|
{ color: '#54B399', percentage: 41 },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
chartAvailable: true,
|
chartAvailable: true,
|
||||||
id: 'rt_responsetime_x_2',
|
id: 'rt_responsetime_x_2',
|
||||||
colorStats: [
|
colorStats: [
|
||||||
{ key: '#54B399', value: 5 },
|
{ color: '#54B399', percentage: 5 },
|
||||||
{ key: '#000000', value: 95 },
|
{ color: '#000000', percentage: 95 },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
@ -8,12 +8,13 @@
|
||||||
import { rgb, nest } from 'd3';
|
import { rgb, nest } from 'd3';
|
||||||
|
|
||||||
interface ColorStat {
|
interface ColorStat {
|
||||||
key: string;
|
color: string;
|
||||||
value: number;
|
percentage: number;
|
||||||
|
pixels?: number;
|
||||||
withinTolerance?: boolean;
|
withinTolerance?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
type ColorStats = ColorStat[];
|
export type CanvasElementColorStats = ColorStat[];
|
||||||
|
|
||||||
import { FtrProviderContext } from '../ftr_provider_context';
|
import { FtrProviderContext } from '../ftr_provider_context';
|
||||||
|
|
||||||
|
@ -75,12 +76,12 @@ export async function CanvasElementProvider({ getService }: FtrProviderContext)
|
||||||
*/
|
*/
|
||||||
public async getColorStats(
|
public async getColorStats(
|
||||||
selector: string,
|
selector: string,
|
||||||
expectedColorStats?: ColorStats,
|
expectedColorStats?: CanvasElementColorStats,
|
||||||
exclude?: string[],
|
exclude?: string[],
|
||||||
percentageThreshold = 5,
|
percentageThreshold = 5,
|
||||||
channelTolerance = 10,
|
channelTolerance = 10,
|
||||||
valueTolerance = 10
|
valueTolerance = 10
|
||||||
): Promise<ColorStats> {
|
): Promise<CanvasElementColorStats> {
|
||||||
const imageData = await this.getImageData(selector);
|
const imageData = await this.getImageData(selector);
|
||||||
// transform the array of RGBA numbers to an array of hex values
|
// transform the array of RGBA numbers to an array of hex values
|
||||||
const colors: string[] = [];
|
const colors: string[] = [];
|
||||||
|
@ -109,21 +110,24 @@ export async function CanvasElementProvider({ getService }: FtrProviderContext)
|
||||||
.filter((s) => getPixelPercentage(s.values.length) >= percentageThreshold)
|
.filter((s) => getPixelPercentage(s.values.length) >= percentageThreshold)
|
||||||
.sort((a, b) => a.key.localeCompare(b.key))
|
.sort((a, b) => a.key.localeCompare(b.key))
|
||||||
.map((s, i) => {
|
.map((s, i) => {
|
||||||
const value = getPixelPercentage(s.values.length);
|
const percentage = getPixelPercentage(s.values.length);
|
||||||
|
const pixels = s.values.length;
|
||||||
return {
|
return {
|
||||||
key: s.key,
|
color: s.key,
|
||||||
value,
|
percentage,
|
||||||
|
pixels,
|
||||||
...(expectedColorStats !== undefined
|
...(expectedColorStats !== undefined
|
||||||
? {
|
? {
|
||||||
withinTolerance:
|
withinTolerance:
|
||||||
this.isValueWithinTolerance(
|
this.isValueWithinTolerance(
|
||||||
value,
|
percentage,
|
||||||
expectedColorStats[i]?.value,
|
pixels,
|
||||||
|
expectedColorStats[i]?.percentage,
|
||||||
valueTolerance
|
valueTolerance
|
||||||
) &&
|
) &&
|
||||||
this.isColorWithinTolerance(
|
this.isColorWithinTolerance(
|
||||||
s.key,
|
s.key,
|
||||||
expectedColorStats[i]?.key,
|
expectedColorStats[i]?.color,
|
||||||
channelTolerance
|
channelTolerance
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
@ -138,12 +142,12 @@ export async function CanvasElementProvider({ getService }: FtrProviderContext)
|
||||||
*/
|
*/
|
||||||
public async getColorStatsWithColorTolerance(
|
public async getColorStatsWithColorTolerance(
|
||||||
selector: string,
|
selector: string,
|
||||||
expectedColorStats: ColorStats,
|
expectedColorStats: CanvasElementColorStats,
|
||||||
exclude?: string[],
|
exclude?: string[],
|
||||||
percentageThreshold = 0,
|
percentageThreshold = 0,
|
||||||
channelTolerance = 10,
|
channelTolerance = 10,
|
||||||
valueTolerance = 10
|
valueTolerance = 10
|
||||||
) {
|
): Promise<CanvasElementColorStats> {
|
||||||
const actualColorStats = await this.getColorStats(
|
const actualColorStats = await this.getColorStats(
|
||||||
selector,
|
selector,
|
||||||
undefined,
|
undefined,
|
||||||
|
@ -154,16 +158,26 @@ export async function CanvasElementProvider({ getService }: FtrProviderContext)
|
||||||
);
|
);
|
||||||
|
|
||||||
return expectedColorStats.map((expectedColor) => {
|
return expectedColorStats.map((expectedColor) => {
|
||||||
const colorPercentageWithinTolerance = actualColorStats
|
const colorsWithinTolerance = actualColorStats.filter((d) =>
|
||||||
.filter((d) => this.isColorWithinTolerance(d.key, expectedColor.key, channelTolerance))
|
this.isColorWithinTolerance(d.color, expectedColor.color, channelTolerance)
|
||||||
.reduce((sum, x) => sum + x.value, 0);
|
);
|
||||||
|
const colorPercentageWithinTolerance = colorsWithinTolerance.reduce(
|
||||||
|
(sum, x) => sum + x.percentage,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
const pixelsWithinTolerance = colorsWithinTolerance.reduce(
|
||||||
|
(sum, x) => sum + (x.pixels || 0),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
key: expectedColor.key,
|
color: expectedColor.color,
|
||||||
value: colorPercentageWithinTolerance,
|
percentage: colorPercentageWithinTolerance,
|
||||||
|
pixels: pixelsWithinTolerance,
|
||||||
withinTolerance: this.isValueWithinTolerance(
|
withinTolerance: this.isValueWithinTolerance(
|
||||||
colorPercentageWithinTolerance,
|
colorPercentageWithinTolerance,
|
||||||
expectedColor.value,
|
pixelsWithinTolerance,
|
||||||
|
expectedColor.percentage,
|
||||||
valueTolerance
|
valueTolerance
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
@ -202,15 +216,24 @@ export async function CanvasElementProvider({ getService }: FtrProviderContext)
|
||||||
/**
|
/**
|
||||||
* Returns if a given value is within the tolerated range of an expected value
|
* Returns if a given value is within the tolerated range of an expected value
|
||||||
*
|
*
|
||||||
* @param actualValue
|
* @param actualPercentage
|
||||||
* @param expectedValue
|
* @param actualPixels
|
||||||
|
* @param expectedPercentage
|
||||||
* @param toleranceRange
|
* @param toleranceRange
|
||||||
* @returns if actualValue is within the tolerance of expectedValue
|
* @returns if actualValue is within the tolerance of expectedValue
|
||||||
*/
|
*/
|
||||||
public isValueWithinTolerance(actualValue: number, expectedValue: number, toleranceRange = 10) {
|
public isValueWithinTolerance(
|
||||||
const lower = expectedValue - toleranceRange / 2;
|
actualPercentage: number,
|
||||||
const upper = expectedValue + toleranceRange / 2;
|
actualPixels: number,
|
||||||
return actualValue > 0 && lower <= actualValue && upper >= actualValue;
|
expectedPercentage: number,
|
||||||
|
toleranceRange = 10
|
||||||
|
) {
|
||||||
|
const lower = expectedPercentage - toleranceRange / 2;
|
||||||
|
const upper = expectedPercentage + toleranceRange / 2;
|
||||||
|
return (
|
||||||
|
// actualPercentage could be rounded to 0 so we check against actualPixels if they are above 0.
|
||||||
|
actualPixels > 0 && lower <= actualPercentage && upper >= actualPercentage
|
||||||
|
);
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,18 +10,13 @@ import { ProvidedType } from '@kbn/test/types/ftr';
|
||||||
|
|
||||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||||
|
|
||||||
|
import type { CanvasElementColorStats } from '../canvas_element';
|
||||||
|
|
||||||
interface SetValueOptions {
|
interface SetValueOptions {
|
||||||
clearWithKeyboard?: boolean;
|
clearWithKeyboard?: boolean;
|
||||||
typeCharByChar?: boolean;
|
typeCharByChar?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
// key: color hex code, e.g. #FF3344
|
|
||||||
// value: the expected percentage of the color to be present in the canvas element
|
|
||||||
export type CanvasElementColorStats = Array<{
|
|
||||||
key: string;
|
|
||||||
value: number;
|
|
||||||
}>;
|
|
||||||
|
|
||||||
export type MlCommonUI = ProvidedType<typeof MachineLearningCommonUIProvider>;
|
export type MlCommonUI = ProvidedType<typeof MachineLearningCommonUIProvider>;
|
||||||
|
|
||||||
export function MachineLearningCommonUIProvider({ getService }: FtrProviderContext) {
|
export function MachineLearningCommonUIProvider({ getService }: FtrProviderContext) {
|
||||||
|
|
|
@ -9,7 +9,8 @@ import expect from '@kbn/expect';
|
||||||
import { DataFrameAnalyticsConfig } from '../../../../plugins/ml/public/application/data_frame_analytics/common';
|
import { DataFrameAnalyticsConfig } from '../../../../plugins/ml/public/application/data_frame_analytics/common';
|
||||||
|
|
||||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||||
import type { CanvasElementColorStats, MlCommonUI } from './common_ui';
|
import type { CanvasElementColorStats } from '../canvas_element';
|
||||||
|
import type { MlCommonUI } from './common_ui';
|
||||||
import { MlApi } from './api';
|
import { MlApi } from './api';
|
||||||
import {
|
import {
|
||||||
isRegressionAnalysis,
|
isRegressionAnalysis,
|
||||||
|
@ -273,6 +274,45 @@ export function MachineLearningDataFrameAnalyticsCreationProvider(
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async setScatterplotMatrixSampleSizeSelectValue(selectValue: string) {
|
||||||
|
await testSubjects.selectValue('mlScatterplotMatrixSampleSizeSelect', selectValue);
|
||||||
|
|
||||||
|
const actualSelectState = await testSubjects.getAttribute(
|
||||||
|
'mlScatterplotMatrixSampleSizeSelect',
|
||||||
|
'value'
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(actualSelectState).to.eql(
|
||||||
|
selectValue,
|
||||||
|
`Sample size should be '${selectValue}' (got '${actualSelectState}')`
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
async getScatterplotMatrixRandomizeQuerySwitchCheckState(): Promise<boolean> {
|
||||||
|
const state = await testSubjects.getAttribute(
|
||||||
|
'mlScatterplotMatrixRandomizeQuerySwitch',
|
||||||
|
'aria-checked'
|
||||||
|
);
|
||||||
|
return state === 'true';
|
||||||
|
},
|
||||||
|
|
||||||
|
async assertScatterplotMatrixRandomizeQueryCheckState(expectedCheckState: boolean) {
|
||||||
|
const actualCheckState = await this.getScatterplotMatrixRandomizeQuerySwitchCheckState();
|
||||||
|
expect(actualCheckState).to.eql(
|
||||||
|
expectedCheckState,
|
||||||
|
`Randomize query check state should be '${expectedCheckState}' (got '${actualCheckState}')`
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
async setScatterplotMatrixRandomizeQueryCheckState(checkState: boolean) {
|
||||||
|
await retry.tryForTime(30000, async () => {
|
||||||
|
if ((await this.getScatterplotMatrixRandomizeQuerySwitchCheckState()) !== checkState) {
|
||||||
|
await testSubjects.click('mlScatterplotMatrixRandomizeQuerySwitch');
|
||||||
|
}
|
||||||
|
await this.assertScatterplotMatrixRandomizeQueryCheckState(checkState);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
async assertTrainingPercentInputExists() {
|
async assertTrainingPercentInputExists() {
|
||||||
await testSubjects.existOrFail('mlAnalyticsCreateJobWizardTrainingPercentSlider');
|
await testSubjects.existOrFail('mlAnalyticsCreateJobWizardTrainingPercentSlider');
|
||||||
},
|
},
|
||||||
|
|
|
@ -10,7 +10,8 @@ import { WebElementWrapper } from 'test/functional/services/lib/web_element_wrap
|
||||||
|
|
||||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||||
|
|
||||||
import type { CanvasElementColorStats, MlCommonUI } from './common_ui';
|
import type { CanvasElementColorStats } from '../canvas_element';
|
||||||
|
import type { MlCommonUI } from './common_ui';
|
||||||
|
|
||||||
export function MachineLearningDataFrameAnalyticsResultsProvider(
|
export function MachineLearningDataFrameAnalyticsResultsProvider(
|
||||||
{ getService }: FtrProviderContext,
|
{ getService }: FtrProviderContext,
|
||||||
|
@ -84,14 +85,60 @@ export function MachineLearningDataFrameAnalyticsResultsProvider(
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async setScatterplotMatrixSampleSizeSelectValue(selectValue: string) {
|
||||||
|
await testSubjects.selectValue('mlScatterplotMatrixSampleSizeSelect', selectValue);
|
||||||
|
|
||||||
|
const actualSelectState = await testSubjects.getAttribute(
|
||||||
|
'mlScatterplotMatrixSampleSizeSelect',
|
||||||
|
'value'
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(actualSelectState).to.eql(
|
||||||
|
selectValue,
|
||||||
|
`Sample size should be '${selectValue}' (got '${actualSelectState}')`
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
async getScatterplotMatrixRandomizeQuerySwitchCheckState(): Promise<boolean> {
|
||||||
|
const state = await testSubjects.getAttribute(
|
||||||
|
'mlScatterplotMatrixRandomizeQuerySwitch',
|
||||||
|
'aria-checked'
|
||||||
|
);
|
||||||
|
return state === 'true';
|
||||||
|
},
|
||||||
|
|
||||||
|
async assertScatterplotMatrixRandomizeQueryCheckState(expectedCheckState: boolean) {
|
||||||
|
const actualCheckState = await this.getScatterplotMatrixRandomizeQuerySwitchCheckState();
|
||||||
|
expect(actualCheckState).to.eql(
|
||||||
|
expectedCheckState,
|
||||||
|
`Randomize query check state should be '${expectedCheckState}' (got '${actualCheckState}')`
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
async setScatterplotMatrixRandomizeQueryCheckState(checkState: boolean) {
|
||||||
|
await retry.tryForTime(30000, async () => {
|
||||||
|
if ((await this.getScatterplotMatrixRandomizeQuerySwitchCheckState()) !== checkState) {
|
||||||
|
await testSubjects.click('mlScatterplotMatrixRandomizeQuerySwitch');
|
||||||
|
}
|
||||||
|
await this.assertScatterplotMatrixRandomizeQueryCheckState(checkState);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
async assertScatterplotMatrix(expectedValue: CanvasElementColorStats) {
|
async assertScatterplotMatrix(expectedValue: CanvasElementColorStats) {
|
||||||
await testSubjects.existOrFail('mlDFExpandableSection-splom > mlScatterplotMatrix loaded', {
|
await testSubjects.existOrFail('mlDFExpandableSection-splom > mlScatterplotMatrix loaded', {
|
||||||
timeout: 5000,
|
timeout: 5000,
|
||||||
});
|
});
|
||||||
await testSubjects.scrollIntoView('mlDFExpandableSection-splom > mlScatterplotMatrix loaded');
|
await testSubjects.scrollIntoView('mlDFExpandableSection-splom > mlScatterplotMatrix loaded');
|
||||||
await mlCommonUI.assertColorsInCanvasElement('mlDFExpandableSection-splom', expectedValue, [
|
await mlCommonUI.assertColorsInCanvasElement(
|
||||||
'#000000',
|
'mlDFExpandableSection-splom',
|
||||||
]);
|
expectedValue,
|
||||||
|
['#000000'],
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
// increased tolerance up from 10 to 20
|
||||||
|
// since the returned randomized colors vary quite a bit on each run.
|
||||||
|
20
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
async assertFeatureImportanceDecisionPathChartElementsExists() {
|
async assertFeatureImportanceDecisionPathChartElementsExists() {
|
||||||
|
|
|
@ -10,6 +10,15 @@ import expect from '@kbn/expect';
|
||||||
|
|
||||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||||
|
|
||||||
|
import type { CanvasElementColorStats } from '../canvas_element';
|
||||||
|
|
||||||
|
export type HistogramCharts = Array<{
|
||||||
|
chartAvailable: boolean;
|
||||||
|
id: string;
|
||||||
|
legend?: string;
|
||||||
|
colorStats?: CanvasElementColorStats;
|
||||||
|
}>;
|
||||||
|
|
||||||
export function TransformWizardProvider({ getService, getPageObjects }: FtrProviderContext) {
|
export function TransformWizardProvider({ getService, getPageObjects }: FtrProviderContext) {
|
||||||
const aceEditor = getService('aceEditor');
|
const aceEditor = getService('aceEditor');
|
||||||
const canvasElement = getService('canvasElement');
|
const canvasElement = getService('canvasElement');
|
||||||
|
@ -224,14 +233,7 @@ export function TransformWizardProvider({ getService, getPageObjects }: FtrProvi
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
async assertIndexPreviewHistogramCharts(
|
async assertIndexPreviewHistogramCharts(expectedHistogramCharts: HistogramCharts) {
|
||||||
expectedHistogramCharts: Array<{
|
|
||||||
chartAvailable: boolean;
|
|
||||||
id: string;
|
|
||||||
legend?: string;
|
|
||||||
colorStats?: any[];
|
|
||||||
}>
|
|
||||||
) {
|
|
||||||
// For each chart, get the content of each header cell and assert
|
// For each chart, get the content of each header cell and assert
|
||||||
// the legend text and column id and if the chart should be present or not.
|
// the legend text and column id and if the chart should be present or not.
|
||||||
await retry.tryForTime(5000, async () => {
|
await retry.tryForTime(5000, async () => {
|
||||||
|
@ -244,7 +246,7 @@ export function TransformWizardProvider({ getService, getPageObjects }: FtrProvi
|
||||||
|
|
||||||
if (expected.colorStats !== undefined) {
|
if (expected.colorStats !== undefined) {
|
||||||
const sortedExpectedColorStats = [...expected.colorStats].sort((a, b) =>
|
const sortedExpectedColorStats = [...expected.colorStats].sort((a, b) =>
|
||||||
a.key.localeCompare(b.key)
|
a.color.localeCompare(b.color)
|
||||||
);
|
);
|
||||||
|
|
||||||
const actualColorStats = await canvasElement.getColorStats(
|
const actualColorStats = await canvasElement.getColorStats(
|
||||||
|
|
Loading…
Reference in a new issue