mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Prometheus: Migrate from aria-label to data-testid for selectors (#78554)
* migrate from aria-label to data-testid for selectors * fix e2e tests with shared components * fix e2e tests with more shared components * pass data-testid to SelectBase component * pass data-testid to value container and traverse the dom to access the input in e2e
This commit is contained in:
parent
f41a0559fa
commit
a9f4ffab5d
@ -669,9 +669,6 @@ exports[`better eslint`] = {
|
||||
"packages/grafana-ui/src/components/PanelChrome/index.ts:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/QueryField/QueryField.tsx:5381": [
|
||||
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Segment/SegmentSelect.tsx:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
],
|
||||
@ -5485,13 +5482,9 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Styles should be written using objects.", "0"],
|
||||
[0, 0, 0, "Styles should be written using objects.", "1"]
|
||||
],
|
||||
"public/app/plugins/datasource/loki/components/LokiQueryEditor.tsx:5381": [
|
||||
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"]
|
||||
],
|
||||
"public/app/plugins/datasource/loki/components/monaco-query-field/MonacoQueryField.tsx:5381": [
|
||||
[0, 0, 0, "Styles should be written using objects.", "0"],
|
||||
[0, 0, 0, "Styles should be written using objects.", "1"],
|
||||
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "2"]
|
||||
[0, 0, 0, "Styles should be written using objects.", "1"]
|
||||
],
|
||||
"public/app/plugins/datasource/loki/configuration/ConfigEditor.tsx:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
|
||||
@ -5662,8 +5655,7 @@ exports[`better eslint`] = {
|
||||
],
|
||||
"public/app/plugins/datasource/prometheus/components/monaco-query-field/MonacoQueryField.tsx:5381": [
|
||||
[0, 0, 0, "Styles should be written using objects.", "0"],
|
||||
[0, 0, 0, "Styles should be written using objects.", "1"],
|
||||
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "2"]
|
||||
[0, 0, 0, "Styles should be written using objects.", "1"]
|
||||
],
|
||||
"public/app/plugins/datasource/prometheus/configuration/AzureCredentialsConfig.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
@ -5708,12 +5700,8 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Styles should be written using objects.", "18"],
|
||||
[0, 0, 0, "Styles should be written using objects.", "19"]
|
||||
],
|
||||
"public/app/plugins/datasource/prometheus/configuration/ExemplarSetting.tsx:5381": [
|
||||
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"]
|
||||
],
|
||||
"public/app/plugins/datasource/prometheus/configuration/ExemplarsSettings.tsx:5381": [
|
||||
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"],
|
||||
[0, 0, 0, "Styles should be written using objects.", "1"]
|
||||
[0, 0, 0, "Styles should be written using objects.", "0"]
|
||||
],
|
||||
"public/app/plugins/datasource/prometheus/datasource.test.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
@ -5774,13 +5762,10 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
|
||||
],
|
||||
"public/app/plugins/datasource/prometheus/querybuilder/components/LabelFilterItem.tsx:5381": [
|
||||
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "1"],
|
||||
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "2"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "3"],
|
||||
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "4"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "5"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "6"]
|
||||
[0, 0, 0, "Do not use any type assertions.", "2"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "3"]
|
||||
],
|
||||
"public/app/plugins/datasource/prometheus/querybuilder/components/LabelFilters.tsx:5381": [
|
||||
[0, 0, 0, "Styles should be written using objects.", "0"]
|
||||
@ -5809,9 +5794,6 @@ exports[`better eslint`] = {
|
||||
"public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryCodeEditor.tsx:5381": [
|
||||
[0, 0, 0, "Styles should be written using objects.", "0"]
|
||||
],
|
||||
"public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryEditorSelector.tsx:5381": [
|
||||
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"]
|
||||
],
|
||||
"public/app/plugins/datasource/prometheus/querybuilder/components/metrics-modal/AdditionalSettings.tsx:5381": [
|
||||
[0, 0, 0, "Styles should be written using objects.", "0"],
|
||||
[0, 0, 0, "Styles should be written using objects.", "1"],
|
||||
@ -5857,18 +5839,15 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
],
|
||||
"public/app/plugins/datasource/prometheus/querybuilder/shared/LabelFilterItem.tsx:5381": [
|
||||
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "1"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "2"],
|
||||
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "3"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "3"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "4"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "5"],
|
||||
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "6"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "6"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "7"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "8"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "9"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "10"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "11"]
|
||||
[0, 0, 0, "Do not use any type assertions.", "8"]
|
||||
],
|
||||
"public/app/plugins/datasource/prometheus/querybuilder/shared/LabelFilters.tsx:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
|
@ -69,11 +69,20 @@ describe('Loki query builder', () => {
|
||||
e2e.components.QueryBuilder.labelSelect().should('be.visible').click();
|
||||
// wait until labels are loaded and set on the component before starting to type
|
||||
cy.wait('@labelsRequest');
|
||||
e2e.components.QueryBuilder.labelSelect().type('instance{enter}');
|
||||
e2e.components.QueryBuilder.matchOperatorSelect().should('be.visible').click().type('=~{enter}');
|
||||
e2e.components.QueryBuilder.labelSelect().children('div').children('input').type('instance{enter}');
|
||||
e2e.components.QueryBuilder.matchOperatorSelect()
|
||||
.should('be.visible')
|
||||
.click()
|
||||
.children('div')
|
||||
.children('input')
|
||||
.type('=~{enter}', { force: true });
|
||||
e2e.components.QueryBuilder.valueSelect().should('be.visible').click();
|
||||
cy.wait('@valuesRequest');
|
||||
e2e.components.QueryBuilder.valueSelect().type('instance1{enter}').type('instance2{enter}');
|
||||
e2e.components.QueryBuilder.valueSelect()
|
||||
.children('div')
|
||||
.children('input')
|
||||
.type('instance1{enter}')
|
||||
.type('instance2{enter}');
|
||||
cy.contains(MISSING_LABEL_FILTER_ERROR_MESSAGE).should('not.exist');
|
||||
cy.contains(finalQuery).should('be.visible');
|
||||
|
||||
|
@ -61,8 +61,8 @@ export const Components = {
|
||||
Prometheus: {
|
||||
configPage: {
|
||||
connectionSettings: 'Data source connection URL',
|
||||
exemplarsAddButton: 'Add exemplar config button',
|
||||
internalLinkSwitch: 'Internal link switch',
|
||||
exemplarsAddButton: 'data-testid Add exemplar config button',
|
||||
internalLinkSwitch: 'data-testid Internal link switch',
|
||||
},
|
||||
exemplarMarker: 'data-testid Exemplar marker',
|
||||
},
|
||||
@ -345,12 +345,12 @@ export const Components = {
|
||||
TraceViewer: {
|
||||
spanBar: 'data-testid SpanBar--wrapper',
|
||||
},
|
||||
QueryField: { container: 'Query field' },
|
||||
QueryField: { container: 'data-testid Query field' },
|
||||
QueryBuilder: {
|
||||
queryPatterns: 'Query patterns',
|
||||
labelSelect: 'Select label',
|
||||
valueSelect: 'Select value',
|
||||
matchOperatorSelect: 'Select match operator',
|
||||
queryPatterns: 'data-testid Query patterns',
|
||||
labelSelect: 'data-testid Select label',
|
||||
valueSelect: 'data-testid Select value',
|
||||
matchOperatorSelect: 'data-testid Select match operator',
|
||||
},
|
||||
ValuePicker: {
|
||||
button: (name: string) => `data-testid Value picker button ${name}`,
|
||||
|
@ -210,7 +210,7 @@ export class UnThemedQueryField extends PureComponent<QueryFieldProps, QueryFiel
|
||||
|
||||
return (
|
||||
<div className={cx(wrapperClassName, styles.wrapper)}>
|
||||
<div className="slate-query-field" aria-label={selectors.components.QueryField.container}>
|
||||
<div className="slate-query-field" data-testid={selectors.components.QueryField.container}>
|
||||
<Editor
|
||||
ref={(editor) => (this.editor = editor!)}
|
||||
schema={SCHEMA}
|
||||
|
@ -73,6 +73,7 @@ export function SelectBase<T, Rest = {}>({
|
||||
allowCustomValue = false,
|
||||
allowCreateWhileLoading = false,
|
||||
'aria-label': ariaLabel,
|
||||
'data-testid': dataTestid,
|
||||
autoFocus = false,
|
||||
backspaceRemovesValue = true,
|
||||
blurInputOnSelect,
|
||||
@ -199,6 +200,7 @@ export function SelectBase<T, Rest = {}>({
|
||||
|
||||
const commonSelectProps = {
|
||||
'aria-label': ariaLabel,
|
||||
'data-testid': dataTestid,
|
||||
autoFocus,
|
||||
backspaceRemovesValue,
|
||||
blurInputOnSelect,
|
||||
|
@ -29,17 +29,21 @@ class UnthemedValueContainer extends Component<any & { theme: GrafanaTheme2 }> {
|
||||
}
|
||||
|
||||
renderContainer(children?: ReactNode) {
|
||||
const { isMulti, theme } = this.props;
|
||||
const { isMulti, theme, selectProps } = this.props;
|
||||
const noWrap = this.props.selectProps?.noMultiValueWrap && !this.props.selectProps?.menuIsOpen;
|
||||
const styles = getSelectStyles(theme);
|
||||
|
||||
const dataTestid = selectProps['data-testid'];
|
||||
const className = cx(
|
||||
styles.valueContainer,
|
||||
isMulti && styles.valueContainerMulti,
|
||||
noWrap && styles.valueContainerMultiNoWrap
|
||||
);
|
||||
|
||||
return <div className={className}>{children}</div>;
|
||||
return (
|
||||
<div data-testid={dataTestid} className={className}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@ export type LoadOptionsCallback<T> = (options: Array<SelectableValue<T>>) => voi
|
||||
export interface SelectCommonProps<T> {
|
||||
/** Aria label applied to the input field */
|
||||
['aria-label']?: string;
|
||||
['data-testid']?: string;
|
||||
allowCreateWhileLoading?: boolean;
|
||||
allowCustomValue?: boolean;
|
||||
/** Focus is set to the Select when rendered*/
|
||||
|
@ -150,7 +150,7 @@ export const LokiQueryEditor = React.memo<LokiQueryEditorProps>((props) => {
|
||||
<EditorHeader>
|
||||
<Stack gap={1}>
|
||||
<Button
|
||||
aria-label={selectors.components.QueryBuilder.queryPatterns}
|
||||
data-testid={selectors.components.QueryBuilder.queryPatterns}
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
|
@ -166,7 +166,7 @@ const MonacoQueryField = ({
|
||||
|
||||
return (
|
||||
<div
|
||||
aria-label={selectors.components.QueryField.container}
|
||||
data-testid={selectors.components.QueryField.container}
|
||||
className={styles.container}
|
||||
// NOTE: we will be setting inline-style-width/height on this element
|
||||
ref={containerRef}
|
||||
|
@ -122,7 +122,7 @@ const MonacoQueryField = (props: Props) => {
|
||||
|
||||
return (
|
||||
<div
|
||||
aria-label={selectors.components.QueryField.container}
|
||||
data-testid={selectors.components.QueryField.container}
|
||||
className={styles.container}
|
||||
// NOTE: we will be setting inline-style-width/height on this element
|
||||
ref={containerRef}
|
||||
|
@ -40,7 +40,7 @@ export default function ExemplarSetting({ value, onChange, onDelete, disabled }:
|
||||
<>
|
||||
<Switch
|
||||
value={isInternalLink}
|
||||
aria-label={selectors.components.DataSource.Prometheus.configPage.internalLinkSwitch}
|
||||
data-testid={selectors.components.DataSource.Prometheus.configPage.internalLinkSwitch}
|
||||
onChange={(ev) => setIsInternalLink(ev.currentTarget.checked)}
|
||||
/>
|
||||
</>
|
||||
|
@ -46,7 +46,7 @@ export function ExemplarsSettings({ options, onChange, disabled }: Props) {
|
||||
{!disabled && (
|
||||
<Button
|
||||
variant="secondary"
|
||||
aria-label={selectors.components.DataSource.Prometheus.configPage.exemplarsAddButton}
|
||||
data-testid={selectors.components.DataSource.Prometheus.configPage.exemplarsAddButton}
|
||||
className={css`
|
||||
margin-bottom: 10px;
|
||||
`}
|
||||
|
@ -81,7 +81,7 @@ export function LabelFilterItem({
|
||||
{/* Label name select, loads all values at once */}
|
||||
<Select
|
||||
placeholder="Select label"
|
||||
aria-label={selectors.components.QueryBuilder.labelSelect}
|
||||
data-testid={selectors.components.QueryBuilder.labelSelect}
|
||||
inputId="prometheus-dimensions-filter-item-key"
|
||||
width="auto"
|
||||
value={item.label ? toOption(item.label) : null}
|
||||
@ -113,7 +113,7 @@ export function LabelFilterItem({
|
||||
|
||||
{/* Operator select i.e. = =~ != !~ */}
|
||||
<Select
|
||||
aria-label={selectors.components.QueryBuilder.matchOperatorSelect}
|
||||
data-testid={selectors.components.QueryBuilder.matchOperatorSelect}
|
||||
className="query-segment-operator"
|
||||
value={toOption(item.op ?? defaultOp)}
|
||||
options={operators}
|
||||
@ -133,7 +133,7 @@ export function LabelFilterItem({
|
||||
{/* Label value async select: autocomplete calls prometheus API */}
|
||||
<AsyncSelect
|
||||
placeholder="Select value"
|
||||
aria-label={selectors.components.QueryBuilder.valueSelect}
|
||||
data-testid={selectors.components.QueryBuilder.valueSelect}
|
||||
inputId="prometheus-dimensions-filter-item-value"
|
||||
width="auto"
|
||||
value={
|
||||
|
@ -116,7 +116,7 @@ export const PromQueryEditorSelector = React.memo<Props>((props) => {
|
||||
/>
|
||||
<EditorHeader>
|
||||
<Button
|
||||
aria-label={selectors.components.QueryBuilder.queryPatterns}
|
||||
data-testid={selectors.components.QueryBuilder.queryPatterns}
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
onClick={() => setQueryPatternsModalOpen((prevValue) => !prevValue)}
|
||||
|
@ -77,7 +77,7 @@ export function LabelFilterItem({
|
||||
<InputGroup>
|
||||
<Select
|
||||
placeholder="Select label"
|
||||
aria-label={selectors.components.QueryBuilder.labelSelect}
|
||||
data-testid={selectors.components.QueryBuilder.labelSelect}
|
||||
inputId="prometheus-dimensions-filter-item-key"
|
||||
width="auto"
|
||||
value={item.label ? toOption(item.label) : null}
|
||||
@ -107,7 +107,7 @@ export function LabelFilterItem({
|
||||
/>
|
||||
|
||||
<Select
|
||||
aria-label={selectors.components.QueryBuilder.matchOperatorSelect}
|
||||
data-testid={selectors.components.QueryBuilder.matchOperatorSelect}
|
||||
value={toOption(item.op ?? defaultOp)}
|
||||
options={operators}
|
||||
width="auto"
|
||||
@ -125,7 +125,7 @@ export function LabelFilterItem({
|
||||
|
||||
<Select
|
||||
placeholder="Select value"
|
||||
aria-label={selectors.components.QueryBuilder.valueSelect}
|
||||
data-testid={selectors.components.QueryBuilder.valueSelect}
|
||||
inputId="prometheus-dimensions-filter-item-value"
|
||||
width="auto"
|
||||
value={
|
||||
|
Loading…
Reference in New Issue
Block a user