Skip to content

Commit

Permalink
[ML] Add initial docs screenshot generation (elastic#121495)
Browse files Browse the repository at this point in the history
This PR utilizes the functional test runner to walk through the UI and take a couple screenshots for use in the documentation.
  • Loading branch information
pheyos authored and kibanamachine committed Dec 20, 2021
1 parent 842adfd commit d79eb2a
Show file tree
Hide file tree
Showing 34 changed files with 1,555 additions and 129 deletions.
4 changes: 2 additions & 2 deletions test/functional/services/common/screenshots.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ export class ScreenshotsService extends FtrService {
}
}

async take(name: string, el?: WebElementWrapper) {
const path = resolve(this.SESSION_DIRECTORY, `${name}.png`);
async take(name: string, el?: WebElementWrapper, subDirectories: string[] = []) {
const path = resolve(this.SESSION_DIRECTORY, ...subDirectories, `${name}.png`);
await this.capture(path, el);
this.failureMetadata.addScreenshot(name, path);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export function getColumns(
})
}
data-row-id={item.rowId}
data-test-subj="mlJobListRowDetailsToggle"
data-test-subj="mlAnomaliesListRowDetailsToggle"
/>
),
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,10 @@ export class AnomalyDetails extends Component {
}),
content: (
<Fragment>
<div className="ml-anomalies-table-details">
<div
className="ml-anomalies-table-details"
data-test-subj="mlAnomaliesListRowDetails"
>
{this.renderDescription()}
<EuiSpacer size="m" />
{this.renderDetails()}
Expand Down Expand Up @@ -633,7 +636,7 @@ export class AnomalyDetails extends Component {
);
} else {
return (
<div className="ml-anomalies-table-details">
<div className="ml-anomalies-table-details" data-test-subj="mlAnomaliesListRowDetails">
{this.renderDescription()}
<EuiSpacer size="m" />
{this.renderDetails()}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export const ExpandableSection: FC<ExpandableSectionProps> = ({
iconType={isExpanded ? 'arrowUp' : 'arrowDown'}
iconSide="right"
flush="left"
data-test-subj={`mlDFExpandableSection-${dataTestId}-toggle-button`}
>
{title}
</EuiButtonEmpty>
Expand Down Expand Up @@ -126,7 +127,12 @@ export const ExpandableSection: FC<ExpandableSectionProps> = ({
)}
</div>
{isExpanded && (
<div className={contentPadding ? 'mlExpandableSection-contentPadding' : ''}>{content}</div>
<div
className={contentPadding ? 'mlExpandableSection-contentPadding' : ''}
data-test-subj={`mlDFExpandableSection-${dataTestId}-content`}
>
{content}
</div>
)}
</EuiPanel>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ export const ExplorationQueryBar: FC<ExplorationQueryBarProps> = ({
})
}
disableAutoFocus={true}
dataTestSubj="transformQueryInput"
dataTestSubj="mlDFAnalyticsQueryInput"
languageSwitcherPopoverAnchorPosition="rightDown"
/>
</EuiFlexItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ export const AnomaliesMap: FC<Props> = ({ anomalies, jobIds }) => {

return (
<>
<EuiPanel>
<EuiPanel data-test-subj="mlAnomaliesMapContainer">
<EuiAccordion
id="mlAnomalyExplorerAnomaliesMapAccordionId"
initialIsOpen={true}
Expand Down
14 changes: 14 additions & 0 deletions x-pack/plugins/ml/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,20 @@ and Kibana instance that the tests will be run against.

ML accessibility tests are located in `x-pack/test/accessibility/apps`.

## Generating docs screenshots

The screenshot generation uses the functional test runner described in the
`Functional tests` section above.

Run the following commands from the `x-pack` directory and use separate terminals
for test server and test runner. The test server command starts an Elasticsearch
and Kibana instance that the tests will be run against.

node scripts/functional_tests_server.js --config test/screenshot_creation/config.ts
node scripts/functional_test_runner.js --config test/screenshot_creation/config.ts --include-tag mlqa

The generated screenshots are stored in `x-pack/test/functional/screenshots/session/ml_docs`.
ML screenshot generation tests are located in `x-pack/test/screenshot_creation/apps/ml_docs`.
## Shared functions

You can find the ML shared functions in the following files in GitHub:
Expand Down
31 changes: 6 additions & 25 deletions x-pack/test/functional/apps/ml/anomaly_detection/custom_urls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,12 @@

import { FtrProviderContext } from '../../../ftr_provider_context';
import { Job, Datafeed } from '../../../../../plugins/ml/common/types/anomaly_detection_jobs';
import {
TimeRangeType,
TIME_RANGE_TYPE,
} from '../../../../../plugins/ml/public/application/jobs/components/custom_url_editor/constants';

interface DiscoverUrlConfig {
label: string;
indexPattern: string;
queryEntityFieldNames: string[];
timeRange: TimeRangeType;
timeRangeInterval?: string;
}

interface DashboardUrlConfig {
label: string;
dashboardName: string;
queryEntityFieldNames: string[];
timeRange: TimeRangeType;
timeRangeInterval?: string;
}

interface OtherUrlConfig {
label: string;
url: string;
}
import { TIME_RANGE_TYPE } from '../../../../../plugins/ml/public/application/jobs/components/custom_url_editor/constants';
import type {
DiscoverUrlConfig,
DashboardUrlConfig,
OtherUrlConfig,
} from '../../../services/ml/job_table';

// @ts-expect-error doesn't implement the full interface
const JOB_CONFIG: Job = {
Expand Down
14 changes: 14 additions & 0 deletions x-pack/test/functional/page_objects/gis_page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,14 @@ export class GisPageObject extends FtrService {
await this.testSubjects.click('layerVisibilityToggleButton');
}

async openLegend() {
const isOpen = await this.testSubjects.exists('mapLayerTOC');
if (isOpen === false) {
await this.testSubjects.click('mapExpandLayerControlButton');
await this.testSubjects.existOrFail('mapLayerTOC');
}
}

async closeLegend() {
const isOpen = await this.testSubjects.exists('mapLayerTOC');
if (isOpen) {
Expand All @@ -294,6 +302,12 @@ export class GisPageObject extends FtrService {
}
}

async clickFitToData() {
this.log.debug('Fit to data');
await this.testSubjects.click('fitToData');
await this.waitForMapPanAndZoom();
}

async clickFitToBounds(layerName: string) {
this.log.debug(`Fit to bounds, layer: ${layerName}`);
const origView = await this.getView();
Expand Down
24 changes: 24 additions & 0 deletions x-pack/test/functional/services/ml/anomalies_table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,5 +149,29 @@ export function MachineLearningAnomaliesTableProvider({ getService }: FtrProvide
await testSubjects.click(`tablePagination-${rowsNumber}-rows`);
await this.assertRowsNumberPerPage(rowsNumber);
},

async ensureDetailsOpen(rowIndex: number) {
await retry.tryForTime(10 * 1000, async () => {
const rowSubj = await this.getRowSubjByRowIndex(rowIndex);
if (!(await testSubjects.exists('mlAnomaliesListRowDetails'))) {
await testSubjects.click(`${rowSubj} > mlAnomaliesListRowDetailsToggle`);
await testSubjects.existOrFail('mlAnomaliesListRowDetails', { timeout: 1000 });
}
});
},

async ensureDetailsClosed(rowIndex: number) {
await retry.tryForTime(10 * 1000, async () => {
const rowSubj = await this.getRowSubjByRowIndex(rowIndex);
if (await testSubjects.exists('mlAnomaliesListRowDetails')) {
await testSubjects.click(`${rowSubj} > mlAnomaliesListRowDetailsToggle`);
await testSubjects.missingOrFail('mlAnomaliesListRowDetails', { timeout: 1000 });
}
});
},

async scrollTableIntoView() {
await testSubjects.scrollIntoView('mlAnomaliesTable');
},
};
}
8 changes: 8 additions & 0 deletions x-pack/test/functional/services/ml/anomaly_explorer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,5 +174,13 @@ export function MachineLearningAnomalyExplorerProvider({
`Expect ${expectedChartsCount} charts to appear, got ${actualChartsCount}`
);
},

async scrollChartsContainerIntoView() {
await testSubjects.scrollIntoView('mlExplorerChartsContainer');
},

async scrollMapContainerIntoView() {
await testSubjects.scrollIntoView('mlAnomaliesMapContainer');
},
};
}
4 changes: 2 additions & 2 deletions x-pack/test/functional/services/ml/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -936,11 +936,11 @@ export function MachineLearningAPIProvider({ getService }: FtrProviderContext) {
log.debug('> DFA job started.');
},

async createAndRunDFAJob(dfaConfig: DataFrameAnalyticsConfig) {
async createAndRunDFAJob(dfaConfig: DataFrameAnalyticsConfig, timeout?: number) {
await this.createDataFrameAnalyticsJob(dfaConfig);
await this.runDFAJob(dfaConfig.id);
await this.waitForDFAJobTrainingRecordCountToBePositive(dfaConfig.id);
await this.waitForAnalyticsState(dfaConfig.id, DATA_FRAME_TASK_STATE.STOPPED);
await this.waitForAnalyticsState(dfaConfig.id, DATA_FRAME_TASK_STATE.STOPPED, timeout);
},

async updateJobSpaces(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ export function MachineLearningDataFrameAnalyticsCreationProvider(
mlApi: MlApi
) {
const headerPage = getPageObject('header');
const commonPage = getPageObject('common');

const testSubjects = getService('testSubjects');
const comboBox = getService('comboBox');
const retry = getService('retry');
Expand All @@ -33,6 +35,10 @@ export function MachineLearningDataFrameAnalyticsCreationProvider(
await testSubjects.existOrFail('mlAnalyticsCreateJobWizardJobTypeSelect');
},

async scrollJobTypeSelectionIntoView() {
await testSubjects.scrollIntoView('mlAnalyticsCreateJobWizardJobTypeSelect');
},

async assertJobTypeSelection(jobTypeAttribute: string) {
await retry.tryForTime(5000, async () => {
await testSubjects.existOrFail(`${jobTypeAttribute} selectedJobType`);
Expand Down Expand Up @@ -324,16 +330,24 @@ export function MachineLearningDataFrameAnalyticsCreationProvider(
await this.assertDependentVariableSelection([dependentVariable]);
},

async assertScatterplotMatrix(expectedValue: CanvasElementColorStats) {
async assertScatterplotMatrixLoaded() {
await testSubjects.existOrFail(
'mlAnalyticsCreateJobWizardScatterplotMatrixPanel > mlScatterplotMatrix loaded',
{
timeout: 5000,
}
);
},

async scrollScatterplotMatrixIntoView() {
await testSubjects.scrollIntoView(
'mlAnalyticsCreateJobWizardScatterplotMatrixPanel > mlScatterplotMatrix loaded'
);
},

async assertScatterplotMatrix(expectedValue: CanvasElementColorStats) {
await this.assertScatterplotMatrixLoaded();
await this.scrollScatterplotMatrixIntoView();
await mlCommonUI.assertColorsInCanvasElement(
'mlAnalyticsCreateJobWizardScatterplotMatrixPanel',
expectedValue,
Expand Down Expand Up @@ -672,5 +686,21 @@ export function MachineLearningDataFrameAnalyticsCreationProvider(
await testSubjects.click('analyticsWizardCardManagement');
await testSubjects.existOrFail('mlPageDataFrameAnalytics');
},

async assertQueryBarValue(expectedValue: string) {
const actualQuery = await testSubjects.getAttribute('mlDFAnalyticsQueryInput', 'value');
expect(actualQuery).to.eql(
expectedValue,
`Query should be '${expectedValue}' (got '${actualQuery}')`
);
},

async setQueryBarValue(query: string) {
await mlCommonUI.setValueWithChecks('mlDFAnalyticsQueryInput', query, {
clearWithKeyboard: true,
});
await commonPage.pressEnterKey();
await this.assertQueryBarValue(query);
},
};
}
54 changes: 52 additions & 2 deletions x-pack/test/functional/services/ml/data_frame_analytics_results.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ export function MachineLearningDataFrameAnalyticsResultsProvider(
await testSubjects.existOrFail('mlDFAnalyticsExplorationTablePanel');
},

async scrollRocCurveChartIntoView() {
await testSubjects.scrollIntoView('mlDFAnalyticsClassificationExplorationRocCurveChart');
},

async assertClassificationEvaluatePanelElementsExists() {
await testSubjects.existOrFail('mlDFExpandableSection-ClassificationEvaluation');
await testSubjects.existOrFail('mlDFAnalyticsClassificationExplorationConfusionMatrix');
Expand Down Expand Up @@ -125,11 +129,15 @@ export function MachineLearningDataFrameAnalyticsResultsProvider(
});
},

async assertScatterplotMatrix(expectedValue: CanvasElementColorStats) {
async assertScatterplotMatrixLoaded() {
await testSubjects.existOrFail('mlDFExpandableSection-splom > mlScatterplotMatrix loaded', {
timeout: 5000,
});
await testSubjects.scrollIntoView('mlDFExpandableSection-splom > mlScatterplotMatrix loaded');
},

async assertScatterplotMatrix(expectedValue: CanvasElementColorStats) {
await this.assertScatterplotMatrixLoaded();
await this.scrollScatterplotMatrixIntoView();
await mlCommonUI.assertColorsInCanvasElement(
'mlDFExpandableSection-splom',
expectedValue,
Expand Down Expand Up @@ -242,5 +250,47 @@ export function MachineLearningDataFrameAnalyticsResultsProvider(
async scrollResultsIntoView() {
await this.scrollContentSectionIntoView('results');
},

async expandContentSection(sectionId: string, shouldExpand: boolean) {
const contentSubj = `mlDFExpandableSection-${sectionId}-content`;
const expandableContentExists = await testSubjects.exists(contentSubj, { timeout: 1000 });

if (expandableContentExists !== shouldExpand) {
await retry.tryForTime(5 * 1000, async () => {
await testSubjects.clickWhenNotDisabled(
`mlDFExpandableSection-${sectionId}-toggle-button`
);
if (shouldExpand) {
await testSubjects.existOrFail(contentSubj, { timeout: 1000 });
} else {
await testSubjects.missingOrFail(contentSubj, { timeout: 1000 });
}
});
}
},

async expandAnalysisSection(shouldExpand: boolean) {
await this.expandContentSection('analysis', shouldExpand);
},

async expandRegressionEvaluationSection(shouldExpand: boolean) {
await this.expandContentSection('RegressionEvaluation', shouldExpand);
},

async expandClassificationEvaluationSection(shouldExpand: boolean) {
await this.expandContentSection('ClassificationEvaluation', shouldExpand);
},

async expandFeatureImportanceSection(shouldExpand: boolean) {
await this.expandContentSection('FeatureImportanceSummary', shouldExpand);
},

async expandScatterplotMatrixSection(shouldExpand: boolean) {
await this.expandContentSection('splom', shouldExpand);
},

async expandResultsSection(shouldExpand: boolean) {
await this.expandContentSection('results', shouldExpand);
},
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ export function MachineLearningDataVisualizerTableProvider(
}

public async setSampleSizeInputValue(
sampleSize: number,
sampleSize: number | 'all',
fieldName: string,
docCountFormatted: string
) {
Expand Down
Loading

0 comments on commit d79eb2a

Please sign in to comment.