Skip to content

Commit 778bb69

Browse files
authored
[ML] Functional Tests: Extend canvas assertion options. (#91473)
Updates the canvas element assertion service and stabilizes tests.
1 parent fc3125a commit 778bb69

File tree

14 files changed

+321
-172
lines changed

14 files changed

+321
-172
lines changed

x-pack/plugins/ml/public/application/_hacks.scss

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
.tab-datavisualizer_index_select,
22
.tab-timeseriesexplorer,
3-
.tab-explorer, {
3+
.tab-explorer {
44
// Make all page background white until More of the pages use EuiPage to wrap in panel-like components
55
background-color: $euiColorEmptyShade;
66
}
@@ -22,3 +22,12 @@
2222
.clear, .clearfix {
2323
clear: both;
2424
}
25+
26+
// Helper class for functional tests to disable anti-aliasing for canvas elements
27+
.mlDisableAntiAliasing {
28+
-webkit-font-smoothing : none;
29+
30+
* canvas {
31+
image-rendering: pixelated;
32+
}
33+
}

x-pack/plugins/ml/public/application/components/scatterplot_matrix/scatterplot_matrix.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ export const ScatterplotMatrix: FC<ScatterplotMatrixProps> = ({
267267
{splom === undefined || vegaSpec === undefined ? (
268268
<VegaChartLoading />
269269
) : (
270-
<div data-test-subj="mlScatterplotMatrix">
270+
<div data-test-subj={`mlScatterplotMatrix ${isLoading ? 'loading' : 'loaded'}`}>
271271
<EuiFlexGroup>
272272
<EuiFlexItem>
273273
<EuiFormRow

x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step_form.tsx

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -120,14 +120,6 @@ export const ConfigurationStepForm: FC<CreateAnalyticsStepProps> = ({
120120
language: SEARCH_QUERY_LANGUAGE.KUERY,
121121
});
122122

123-
const scatterplotFieldOptions = useMemo(
124-
() =>
125-
includesTableItems
126-
.filter((d) => d.feature_type === 'numerical' && d.is_included)
127-
.map((d) => d.name),
128-
[includesTableItems]
129-
);
130-
131123
const toastNotifications = getToastNotifications();
132124

133125
const setJobConfigQuery: ExplorationQueryBarProps['setSearchQuery'] = (update) => {
@@ -341,16 +333,37 @@ export const ConfigurationStepForm: FC<CreateAnalyticsStepProps> = ({
341333
[currentIndexPattern.fields]
342334
);
343335

336+
const scatterplotMatrixProps = useMemo(
337+
() => ({
338+
color: isJobTypeWithDepVar ? dependentVariable : undefined,
339+
fields: includesTableItems
340+
.filter((d) => d.feature_type === 'numerical' && d.is_included)
341+
.map((d) => d.name),
342+
index: currentIndexPattern.title,
343+
legendType: getScatterplotMatrixLegendType(jobType),
344+
searchQuery: jobConfigQuery,
345+
}),
346+
[
347+
currentIndexPattern.title,
348+
dependentVariable,
349+
includesTableItems,
350+
isJobTypeWithDepVar,
351+
jobConfigQuery,
352+
jobType,
353+
]
354+
);
355+
344356
// Show the Scatterplot Matrix only if
345357
// - There's more than one suitable field available
346358
// - The job type is outlier detection, or
347359
// - The job type is regression or classification and the dependent variable has been set
348-
const showScatterplotMatrix =
349-
(jobType === ANALYSIS_CONFIG_TYPE.OUTLIER_DETECTION ||
350-
((jobType === ANALYSIS_CONFIG_TYPE.REGRESSION ||
351-
jobType === ANALYSIS_CONFIG_TYPE.CLASSIFICATION) &&
352-
!dependentVariableEmpty)) &&
353-
scatterplotFieldOptions.length > 1;
360+
const showScatterplotMatrix = useMemo(
361+
() =>
362+
(jobType === ANALYSIS_CONFIG_TYPE.OUTLIER_DETECTION ||
363+
(isJobTypeWithDepVar && !dependentVariableEmpty)) &&
364+
scatterplotMatrixProps.fields.length > 1,
365+
[dependentVariableEmpty, jobType, scatterplotMatrixProps.fields.length]
366+
);
354367

355368
// Don't render until `savedSearchQuery` has been initialized.
356369
// `undefined` means uninitialized, `null` means initialized but not used.
@@ -550,18 +563,7 @@ export const ConfigurationStepForm: FC<CreateAnalyticsStepProps> = ({
550563
paddingSize="m"
551564
data-test-subj="mlAnalyticsCreateJobWizardScatterplotMatrixPanel"
552565
>
553-
<ScatterplotMatrix
554-
fields={scatterplotFieldOptions}
555-
index={currentIndexPattern.title}
556-
color={
557-
jobType === ANALYSIS_CONFIG_TYPE.REGRESSION ||
558-
jobType === ANALYSIS_CONFIG_TYPE.CLASSIFICATION
559-
? dependentVariable
560-
: undefined
561-
}
562-
legendType={getScatterplotMatrixLegendType(jobType)}
563-
searchQuery={jobConfigQuery}
564-
/>
566+
<ScatterplotMatrix {...scatterplotMatrixProps} />
565567
</EuiPanel>
566568
<EuiSpacer />
567569
</>

x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/get_roc_curve_chart_vega_lite_spec.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export const getRocCurveChartVegaLiteSpec = (
5353

5454
return {
5555
$schema: 'https://vega.github.io/schema/vega-lite/v4.8.1.json',
56+
background: 'transparent',
5657
// Left padding of 45px to align the left axis of the chart with the confusion matrix above.
5758
padding: { left: 45, top: 0, right: 0, bottom: 0 },
5859
config: {

x-pack/test/functional/apps/ml/data_frame_analytics/classification_creation.ts

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ export default function ({ getService }: FtrProviderContext) {
1212
const ml = getService('ml');
1313
const editedDescription = 'Edited description';
1414

15-
// Failing: See https://github.com/elastic/kibana/issues/91450
16-
describe.skip('classification creation', function () {
15+
describe('classification creation', function () {
1716
before(async () => {
1817
await esArchiver.loadIfNeeded('ml/bm_classification');
1918
await ml.testResources.createIndexPatternIfNeeded('ft_bank_marketing', '@timestamp');
@@ -43,24 +42,21 @@ export default function ({ getService }: FtrProviderContext) {
4342
createIndexPattern: true,
4443
expected: {
4544
rocCurveColorState: [
46-
// background
47-
{ key: '#FFFFFF', value: 93 },
4845
// tick/grid/axis
49-
{ key: '#98A2B3', value: 1 },
50-
{ key: '#DDDDDD', value: 3 },
51-
// line
52-
{ key: '#6092C0', value: 1 },
46+
{ key: '#DDDDDD', value: 50 },
47+
// lines
48+
{ key: '#98A2B3', value: 30 },
49+
{ key: '#6092C0', value: 10 },
50+
{ key: '#5F92C0', value: 6 },
5351
],
5452
scatterplotMatrixColorStats: [
55-
// background
56-
{ key: '#000000', value: 94 },
53+
// marker colors
54+
{ key: '#7FC6B3', value: 1 },
55+
{ key: '#88ADD0', value: 0.03 },
5756
// tick/grid/axis
58-
{ key: '#DDDDDD', value: 1 },
59-
{ key: '#D3DAE6', value: 1 },
60-
{ key: '#F5F7FA', value: 1 },
61-
// scatterplot circles
62-
{ key: '#6A717D', value: 1 },
63-
{ key: '#54B39A', value: 1 },
57+
{ key: '#DDDDDD', value: 8 },
58+
{ key: '#D3DAE6', value: 8 },
59+
{ key: '#F5F7FA', value: 20 },
6460
],
6561
row: {
6662
type: 'classification',
@@ -112,8 +108,7 @@ export default function ({ getService }: FtrProviderContext) {
112108
await ml.dataFrameAnalyticsCreation.assertIncludeFieldsSelectionExists();
113109

114110
await ml.testExecution.logTestStep('displays the scatterplot matrix');
115-
await ml.dataFrameAnalyticsCanvasElement.assertCanvasElement(
116-
'mlAnalyticsCreateJobWizardScatterplotMatrixFormRow',
111+
await ml.dataFrameAnalyticsCreation.assertScatterplotMatrix(
117112
testData.expected.scatterplotMatrixColorStats
118113
);
119114

@@ -157,7 +152,12 @@ export default function ({ getService }: FtrProviderContext) {
157152

158153
await ml.testExecution.logTestStep('checks validation callouts exist');
159154
await ml.dataFrameAnalyticsCreation.assertValidationCalloutsExists();
160-
await ml.dataFrameAnalyticsCreation.assertAllValidationCalloutsPresent(3);
155+
// Expect the follow callouts:
156+
// - ✓ Dependent variable
157+
// - ✓ Training percent
158+
// - ✓ Top classes
159+
// - ⚠ Analysis fields
160+
await ml.dataFrameAnalyticsCreation.assertAllValidationCalloutsPresent(4);
161161

162162
await ml.testExecution.logTestStep('continues to the create step');
163163
await ml.dataFrameAnalyticsCreation.continueToCreateStep();
@@ -238,16 +238,21 @@ export default function ({ getService }: FtrProviderContext) {
238238
await ml.testExecution.logTestStep('displays the results view for created job');
239239
await ml.dataFrameAnalyticsTable.openResultsView(testData.jobId);
240240
await ml.dataFrameAnalyticsResults.assertClassificationEvaluatePanelElementsExists();
241-
await ml.dataFrameAnalyticsCanvasElement.assertCanvasElement(
241+
await ml.commonUI.assertColorsInCanvasElement(
242242
'mlDFAnalyticsClassificationExplorationRocCurveChart',
243-
testData.expected.rocCurveColorState
243+
testData.expected.rocCurveColorState,
244+
['#000000'],
245+
undefined,
246+
undefined,
247+
// increased tolerance for ROC curve chart up from 10 to 20
248+
// since the returned colors vary quite a bit on each run.
249+
20
244250
);
245251
await ml.dataFrameAnalyticsResults.assertClassificationTablePanelExists();
246252
await ml.dataFrameAnalyticsResults.assertResultsTableExists();
247253
await ml.dataFrameAnalyticsResults.assertResultsTableTrainingFiltersExist();
248254
await ml.dataFrameAnalyticsResults.assertResultsTableNotEmpty();
249-
await ml.dataFrameAnalyticsCanvasElement.assertCanvasElement(
250-
'mlDFExpandableSection-splom',
255+
await ml.dataFrameAnalyticsResults.assertScatterplotMatrix(
251256
testData.expected.scatterplotMatrixColorStats
252257
);
253258
});

x-pack/test/functional/apps/ml/data_frame_analytics/outlier_detection_creation.ts

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ export default function ({ getService }: FtrProviderContext) {
1212
const ml = getService('ml');
1313
const editedDescription = 'Edited description';
1414

15-
// FAILING: https://github.com/elastic/kibana/issues/94854
16-
describe.skip('outlier detection creation', function () {
15+
describe('outlier detection creation', function () {
1716
before(async () => {
1817
await esArchiver.loadIfNeeded('ml/ihp_outlier');
1918
await ml.testResources.createIndexPatternIfNeeded('ft_ihp_outlier', '@timestamp');
@@ -51,26 +50,21 @@ export default function ({ getService }: FtrProviderContext) {
5150
{ chartAvailable: true, id: 'Exterior2nd', legend: '3 categories' },
5251
{ chartAvailable: true, id: 'Fireplaces', legend: '0 - 3' },
5352
],
54-
scatterplotMatrixColorStatsWizard: [
55-
// background
56-
{ key: '#000000', value: 91 },
57-
// tick/grid/axis
58-
{ key: '#6A717D', value: 2 },
59-
{ key: '#F5F7FA', value: 2 },
60-
{ key: '#D3DAE6', value: 1 },
61-
// scatterplot circles
62-
{ key: '#69707D', value: 1 },
63-
{ key: '#98A1B3', value: 1 },
53+
scatterplotMatrixColorsWizard: [
54+
// markers
55+
{ key: '#52B398', value: 25 },
56+
// grey boilerplate
57+
{ key: '#6A717D', value: 30 },
6458
],
6559
scatterplotMatrixColorStatsResults: [
66-
// background
67-
{ key: '#000000', value: 91 },
60+
// red markers
61+
{ key: '#D98071', value: 1 },
6862
// tick/grid/axis, grey markers
69-
// the red outlier color is not above the 1% threshold.
70-
{ key: '#6A717D', value: 2 },
71-
{ key: '#98A2B3', value: 1 },
72-
{ key: '#F5F7FA', value: 2 },
73-
{ key: '#D3DAE6', value: 1 },
63+
{ key: '#6A717D', value: 30 },
64+
{ key: '#D3DAE6', value: 8 },
65+
{ key: '#98A1B3', value: 25 },
66+
// anti-aliasing
67+
{ key: '#F5F7FA', value: 27 },
7468
],
7569
row: {
7670
type: 'outlier_detection',
@@ -94,6 +88,10 @@ export default function ({ getService }: FtrProviderContext) {
9488
await ml.navigation.navigateToDataFrameAnalytics();
9589

9690
await ml.testExecution.logTestStep('loads the source selection modal');
91+
92+
// Disable anti-aliasing to stabilize canvas image rendering assertions
93+
await ml.commonUI.disableAntiAliasing();
94+
9795
await ml.dataFrameAnalytics.startAnalyticsCreation();
9896

9997
await ml.testExecution.logTestStep(
@@ -129,9 +127,8 @@ export default function ({ getService }: FtrProviderContext) {
129127
await ml.dataFrameAnalyticsCreation.assertIncludeFieldsSelectionExists();
130128

131129
await ml.testExecution.logTestStep('displays the scatterplot matrix');
132-
await ml.dataFrameAnalyticsCanvasElement.assertCanvasElement(
133-
'mlAnalyticsCreateJobWizardScatterplotMatrixFormRow',
134-
testData.expected.scatterplotMatrixColorStatsWizard
130+
await ml.dataFrameAnalyticsCreation.assertScatterplotMatrix(
131+
testData.expected.scatterplotMatrixColorsWizard
135132
);
136133

137134
await ml.testExecution.logTestStep('continues to the additional options step');
@@ -258,8 +255,7 @@ export default function ({ getService }: FtrProviderContext) {
258255
await ml.dataFrameAnalyticsResults.assertResultsTableExists();
259256
await ml.dataFrameAnalyticsResults.assertResultsTableNotEmpty();
260257
await ml.dataFrameAnalyticsResults.assertFeatureInfluenceCellNotEmpty();
261-
await ml.dataFrameAnalyticsCanvasElement.assertCanvasElement(
262-
'mlDFExpandableSection-splom',
258+
await ml.dataFrameAnalyticsResults.assertScatterplotMatrix(
263259
testData.expected.scatterplotMatrixColorStatsResults
264260
);
265261
});

x-pack/test/functional/apps/ml/data_frame_analytics/regression_creation.ts

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,13 @@ export default function ({ getService }: FtrProviderContext) {
4141
createIndexPattern: true,
4242
expected: {
4343
scatterplotMatrixColorStats: [
44-
// background
45-
{ key: '#000000', value: 80 },
44+
// some marker colors of the continuous color scale
45+
{ key: '#61AFA3', value: 2 },
46+
{ key: '#D1E5E0', value: 2 },
4647
// tick/grid/axis
47-
{ key: '#6A717D', value: 1 },
48-
{ key: '#F5F7FA', value: 2 },
49-
{ key: '#D3DAE6', value: 1 },
50-
// because a continuous color scale is used for the scatterplot circles,
51-
// none of the generated colors is above the 1% threshold.
48+
{ key: '#6A717D', value: 10 },
49+
{ key: '#F5F7FA', value: 12 },
50+
{ key: '#D3DAE6', value: 3 },
5251
],
5352
row: {
5453
type: 'regression',
@@ -101,8 +100,7 @@ export default function ({ getService }: FtrProviderContext) {
101100
await ml.dataFrameAnalyticsCreation.assertIncludeFieldsSelectionExists();
102101

103102
await ml.testExecution.logTestStep('displays the scatterplot matrix');
104-
await ml.dataFrameAnalyticsCanvasElement.assertCanvasElement(
105-
'mlAnalyticsCreateJobWizardScatterplotMatrixFormRow',
103+
await ml.dataFrameAnalyticsCreation.assertScatterplotMatrix(
106104
testData.expected.scatterplotMatrixColorStats
107105
);
108106

@@ -231,8 +229,7 @@ export default function ({ getService }: FtrProviderContext) {
231229
await ml.dataFrameAnalyticsResults.assertResultsTableExists();
232230
await ml.dataFrameAnalyticsResults.assertResultsTableTrainingFiltersExist();
233231
await ml.dataFrameAnalyticsResults.assertResultsTableNotEmpty();
234-
await ml.dataFrameAnalyticsCanvasElement.assertCanvasElement(
235-
'mlDFExpandableSection-splom',
232+
await ml.dataFrameAnalyticsResults.assertScatterplotMatrix(
236233
testData.expected.scatterplotMatrixColorStats
237234
);
238235
});

0 commit comments

Comments
 (0)