Dashboards: Migrate from aria-label e2e selectors to data-testid (#78536)

* Dashboards: Migrate from aria-label e2e selectors to data-testid

* more changes

* addPanelwidget

* Test: Update .betterer.results

* refactor: fix e2e tests

* refactor: fix failing test

* refactor: update plugin-e2e after adding selector changes to the packege

---------

Co-authored-by: Laura Benz <48948963+L-M-K-B@users.noreply.github.com>
Co-authored-by: Laura Benz <laura.benz@grafana.com>
This commit is contained in:
Khushi Jain 2024-04-24 18:46:19 +05:30 committed by GitHub
parent 38917c4e79
commit 5dd8353ab1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 49 additions and 65 deletions

View File

@ -2408,9 +2408,6 @@ exports[`better eslint`] = {
"public/app/features/dashboard-scene/inspect/HelpWizard/utils.ts:5381": [ "public/app/features/dashboard-scene/inspect/HelpWizard/utils.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"] [0, 0, 0, "Do not use any type assertions.", "0"]
], ],
"public/app/features/dashboard-scene/inspect/InspectJsonTab.tsx:5381": [
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"]
],
"public/app/features/dashboard-scene/pages/DashboardScenePage.tsx:5381": [ "public/app/features/dashboard-scene/pages/DashboardScenePage.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"], [0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"],
@ -2518,11 +2515,7 @@ exports[`better eslint`] = {
], ],
"public/app/features/dashboard/components/AnnotationSettings/AnnotationSettingsEdit.tsx:5381": [ "public/app/features/dashboard/components/AnnotationSettings/AnnotationSettingsEdit.tsx:5381": [
[0, 0, 0, "\'HorizontalGroup\' import from \'@grafana/ui\' is restricted from being used by a pattern. Use Stack component instead.", "0"], [0, 0, 0, "\'HorizontalGroup\' import from \'@grafana/ui\' is restricted from being used by a pattern. Use Stack component instead.", "0"],
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "1"], [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, "Use data-testid for E2E selectors instead of aria-label", "3"],
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "4"],
[0, 0, 0, "Styles should be written using objects.", "5"]
], ],
"public/app/features/dashboard/components/AnnotationSettings/AnnotationSettingsList.tsx:5381": [ "public/app/features/dashboard/components/AnnotationSettings/AnnotationSettingsList.tsx:5381": [
[0, 0, 0, "Styles should be written using objects.", "0"] [0, 0, 0, "Styles should be written using objects.", "0"]
@ -2620,15 +2613,10 @@ exports[`better eslint`] = {
[0, 0, 0, "Styles should be written using objects.", "2"] [0, 0, 0, "Styles should be written using objects.", "2"]
], ],
"public/app/features/dashboard/components/PanelEditor/OptionsPane.tsx:5381": [ "public/app/features/dashboard/components/PanelEditor/OptionsPane.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.", "0"],
[0, 0, 0, "Styles should be written using objects.", "1"], [0, 0, 0, "Styles should be written using objects.", "1"],
[0, 0, 0, "Styles should be written using objects.", "2"], [0, 0, 0, "Styles should be written using objects.", "2"],
[0, 0, 0, "Styles should be written using objects.", "3"], [0, 0, 0, "Styles should be written using objects.", "3"]
[0, 0, 0, "Styles should be written using objects.", "4"]
],
"public/app/features/dashboard/components/PanelEditor/OptionsPaneCategory.tsx:5381": [
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"],
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "1"]
], ],
"public/app/features/dashboard/components/PanelEditor/OptionsPaneItemDescriptor.tsx:5381": [ "public/app/features/dashboard/components/PanelEditor/OptionsPaneItemDescriptor.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "0"],
@ -2658,20 +2646,17 @@ exports[`better eslint`] = {
], ],
"public/app/features/dashboard/components/PanelEditor/PanelEditor.tsx:5381": [ "public/app/features/dashboard/components/PanelEditor/PanelEditor.tsx:5381": [
[0, 0, 0, "\'HorizontalGroup\' import from \'@grafana/ui\' is restricted from being used by a pattern. Use Stack component instead.", "0"], [0, 0, 0, "\'HorizontalGroup\' import from \'@grafana/ui\' is restricted from being used by a pattern. Use Stack component instead.", "0"],
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "1"], [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, "Styles should be written using objects.", "2"],
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "3"], [0, 0, 0, "Styles should be written using objects.", "3"],
[0, 0, 0, "Do not use any type assertions.", "4"], [0, 0, 0, "Styles should be written using objects.", "4"],
[0, 0, 0, "Styles should be written using objects.", "5"], [0, 0, 0, "Styles should be written using objects.", "5"],
[0, 0, 0, "Styles should be written using objects.", "6"], [0, 0, 0, "Styles should be written using objects.", "6"],
[0, 0, 0, "Styles should be written using objects.", "7"], [0, 0, 0, "Styles should be written using objects.", "7"],
[0, 0, 0, "Styles should be written using objects.", "8"], [0, 0, 0, "Styles should be written using objects.", "8"],
[0, 0, 0, "Styles should be written using objects.", "9"], [0, 0, 0, "Styles should be written using objects.", "9"],
[0, 0, 0, "Styles should be written using objects.", "10"], [0, 0, 0, "Styles should be written using objects.", "10"],
[0, 0, 0, "Styles should be written using objects.", "11"], [0, 0, 0, "Styles should be written using objects.", "11"]
[0, 0, 0, "Styles should be written using objects.", "12"],
[0, 0, 0, "Styles should be written using objects.", "13"],
[0, 0, 0, "Styles should be written using objects.", "14"]
], ],
"public/app/features/dashboard/components/PanelEditor/PanelEditorTabs.tsx:5381": [ "public/app/features/dashboard/components/PanelEditor/PanelEditorTabs.tsx:5381": [
[0, 0, 0, "Styles should be written using objects.", "0"], [0, 0, 0, "Styles should be written using objects.", "0"],
@ -3691,9 +3676,6 @@ exports[`better eslint`] = {
"public/app/features/inspector/InspectDataTab.tsx:5381": [ "public/app/features/inspector/InspectDataTab.tsx:5381": [
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"] [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"]
], ],
"public/app/features/inspector/InspectJSONTab.tsx:5381": [
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"]
],
"public/app/features/inspector/InspectStatsTab.tsx:5381": [ "public/app/features/inspector/InspectStatsTab.tsx:5381": [
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"], [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.", "1"]

View File

@ -18,19 +18,21 @@ describe('Annotations filtering', () => {
.should('be.visible') .should('be.visible')
.within(() => { .within(() => {
// All panels // All panels
e2e.components.Annotations.annotationsTypeInput().click({ force: true }).type('All panels{enter}'); e2e.components.Annotations.annotationsTypeInput().find('input').type('All panels{enter}', { force: true });
e2e.components.Annotations.annotationsChoosePanelInput().should('not.exist'); e2e.components.Annotations.annotationsChoosePanelInput().should('not.exist');
// All panels except // All panels except
e2e.components.Annotations.annotationsTypeInput().click({ force: true }).type('All panels except{enter}'); e2e.components.Annotations.annotationsTypeInput()
.find('input')
.type('All panels except{enter}', { force: true });
e2e.components.Annotations.annotationsChoosePanelInput().should('be.visible'); e2e.components.Annotations.annotationsChoosePanelInput().should('be.visible');
// Selected panels // Selected panels
e2e.components.Annotations.annotationsTypeInput().click({ force: true }).type('Selected panels{enter}'); e2e.components.Annotations.annotationsTypeInput().find('input').type('Selected panels{enter}', { force: true });
e2e.components.Annotations.annotationsChoosePanelInput() e2e.components.Annotations.annotationsChoosePanelInput()
.should('be.visible') .should('be.visible')
.click({ force: true }) .find('input')
.type('Panel two{enter}'); .type('Panel two{enter}', { force: true });
}); });
e2e.pages.Dashboard.Settings.Annotations.NewAnnotation.previewInDashboard().click({ force: true }); e2e.pages.Dashboard.Settings.Annotations.NewAnnotation.previewInDashboard().click({ force: true });

View File

@ -74,7 +74,7 @@
"@emotion/eslint-plugin": "11.11.0", "@emotion/eslint-plugin": "11.11.0",
"@grafana/eslint-config": "7.0.0", "@grafana/eslint-config": "7.0.0",
"@grafana/eslint-plugin": "link:./packages/grafana-eslint-rules", "@grafana/eslint-plugin": "link:./packages/grafana-eslint-rules",
"@grafana/plugin-e2e": "1.1.1", "@grafana/plugin-e2e": "1.2.0",
"@grafana/tsconfig": "^1.3.0-rc1", "@grafana/tsconfig": "^1.3.0-rc1",
"@manypkg/get-packages": "^2.2.0", "@manypkg/get-packages": "^2.2.0",
"@playwright/test": "1.43.1", "@playwright/test": "1.43.1",

View File

@ -218,22 +218,22 @@ export const Components = {
}, },
PanelEditor: { PanelEditor: {
General: { General: {
content: 'Panel editor content', content: 'data-testid Panel editor content',
}, },
OptionsPane: { OptionsPane: {
content: 'Panel editor option pane content', content: 'data-testid Panel editor option pane content',
select: 'Panel editor option pane select', select: 'Panel editor option pane select',
fieldLabel: (type: string) => `${type} field property editor`, fieldLabel: (type: string) => `${type} field property editor`,
fieldInput: (title: string) => `data-testid Panel editor option pane field input ${title}`, fieldInput: (title: string) => `data-testid Panel editor option pane field input ${title}`,
}, },
// not sure about the naming *DataPane* // not sure about the naming *DataPane*
DataPane: { DataPane: {
content: 'Panel editor data pane content', content: 'data-testid Panel editor data pane content',
}, },
applyButton: 'data-testid Apply changes and go back to dashboard', applyButton: 'data-testid Apply changes and go back to dashboard',
toggleVizPicker: 'data-testid toggle-viz-picker', toggleVizPicker: 'data-testid toggle-viz-picker',
toggleVizOptions: 'data-testid toggle-viz-options', toggleVizOptions: 'data-testid toggle-viz-options',
toggleTableView: 'toggle-table-view', toggleTableView: 'data-testid toggle-table-view',
// [Geomap] Map controls // [Geomap] Map controls
showZoomField: 'Map controls Show zoom control field property editor', showZoomField: 'Map controls Show zoom control field property editor',
@ -252,7 +252,7 @@ export const Components = {
content: 'Panel inspector Stats content', content: 'Panel inspector Stats content',
}, },
Json: { Json: {
content: 'Panel inspector Json content', content: 'data-testid Panel inspector Json content',
}, },
Query: { Query: {
content: 'Panel inspector Query content', content: 'Panel inspector Query content',
@ -377,8 +377,9 @@ export const Components = {
backArrow: 'data-testid Go Back', backArrow: 'data-testid Go Back',
}, },
OptionsGroup: { OptionsGroup: {
group: (title?: string) => (title ? `Options group ${title}` : 'Options group'), group: (title?: string) => (title ? `data-testid Options group ${title}` : 'data-testid Options group'),
toggle: (title?: string) => (title ? `Options group ${title} toggle` : 'Options group toggle'), toggle: (title?: string) =>
title ? `data-testid Options group ${title} toggle` : 'data-testid Options group toggle',
}, },
PluginVisualization: { PluginVisualization: {
item: (title: string) => `Plugin visualization item ${title}`, item: (title: string) => `Plugin visualization item ${title}`,
@ -535,8 +536,8 @@ export const Components = {
variableOption: 'data-testid variable-option', variableOption: 'data-testid variable-option',
}, },
Annotations: { Annotations: {
annotationsTypeInput: 'annotations-type-input', annotationsTypeInput: 'data-testid annotations-type-input',
annotationsChoosePanelInput: 'choose-panels-input', annotationsChoosePanelInput: 'data-testid choose-panels-input',
editor: { editor: {
testButton: 'data-testid annotations-test-button', testButton: 'data-testid annotations-test-button',
resultContainer: 'data-testid annotations-query-result-container', resultContainer: 'data-testid annotations-query-result-container',

View File

@ -43,9 +43,9 @@ export const Pages = {
AddDashboard: { AddDashboard: {
url: '/dashboard/new', url: '/dashboard/new',
itemButton: (title: string) => `data-testid ${title}`, itemButton: (title: string) => `data-testid ${title}`,
addNewPanel: 'Add new panel', addNewPanel: 'data-testid Add new panel',
addNewRow: 'Add new row', addNewRow: 'data-testid Add new row',
addNewPanelLibrary: 'Add new panel from panel library', addNewPanelLibrary: 'data-testid Add new panel from panel library',
}, },
Dashboard: { Dashboard: {
url: (uid: string) => `/d/${uid}`, url: (uid: string) => `/d/${uid}`,
@ -103,11 +103,11 @@ export const Pages = {
annotations: 'data-testid list-annotations', annotations: 'data-testid list-annotations',
}, },
Settings: { Settings: {
name: 'Annotations settings name input', name: 'data-testid Annotations settings name input',
}, },
NewAnnotation: { NewAnnotation: {
panelFilterSelect: 'data-testid annotations-panel-filter', panelFilterSelect: 'data-testid annotations-panel-filter',
showInLabel: 'show-in-label', showInLabel: 'data-testid show-in-label',
previewInDashboard: 'data-testid annotations-preview', previewInDashboard: 'data-testid annotations-preview',
delete: 'data-testid annotations-delete', delete: 'data-testid annotations-delete',
apply: 'data-testid annotations-apply', apply: 'data-testid annotations-apply',

View File

@ -163,7 +163,7 @@ export class InspectJsonTab extends SceneObjectBase<InspectJsonTabState> {
return ( return (
<div className={styles.wrap}> <div className={styles.wrap}>
<div className={styles.toolbar} aria-label={selectors.components.PanelInspector.Json.content}> <div className={styles.toolbar} data-testid={selectors.components.PanelInspector.Json.content}>
<Field label={t('dashboard.inspect-json.select-source', 'Select source')} className="flex-grow-1"> <Field label={t('dashboard.inspect-json.select-source', 'Select source')} className="flex-grow-1">
<Select <Select
inputId="select-source-dropdown" inputId="select-source-dropdown"

View File

@ -177,7 +177,7 @@ export const AnnotationSettingsEdit = ({ editIdx, dashboard }: Props) => {
<FieldSet className={styles.settingsForm}> <FieldSet className={styles.settingsForm}>
<Field label="Name"> <Field label="Name">
<Input <Input
aria-label={selectors.pages.Dashboard.Settings.Annotations.Settings.name} data-testid={selectors.pages.Dashboard.Settings.Annotations.Settings.name}
name="name" name="name"
id="name" id="name"
autoFocus={isNewAnnotation} autoFocus={isNewAnnotation}
@ -202,13 +202,13 @@ export const AnnotationSettingsEdit = ({ editIdx, dashboard }: Props) => {
<ColorValueEditor value={annotation?.iconColor} onChange={onColorChange} /> <ColorValueEditor value={annotation?.iconColor} onChange={onColorChange} />
</HorizontalGroup> </HorizontalGroup>
</Field> </Field>
<Field label="Show in" aria-label={selectors.pages.Dashboard.Settings.Annotations.NewAnnotation.showInLabel}> <Field label="Show in" data-testid={selectors.pages.Dashboard.Settings.Annotations.NewAnnotation.showInLabel}>
<> <>
<Select <Select
options={panelFilters} options={panelFilters}
value={panelFilter} value={panelFilter}
onChange={onFilterTypeChange} onChange={onFilterTypeChange}
aria-label={selectors.components.Annotations.annotationsTypeInput} data-testid={selectors.components.Annotations.annotationsTypeInput}
/> />
{panelFilter !== PanelFilterType.AllPanels && ( {panelFilter !== PanelFilterType.AllPanels && (
<MultiSelect <MultiSelect
@ -220,7 +220,7 @@ export const AnnotationSettingsEdit = ({ editIdx, dashboard }: Props) => {
width={100} width={100}
closeMenuOnSelect={false} closeMenuOnSelect={false}
className={styles.select} className={styles.select}
aria-label={selectors.components.Annotations.annotationsChoosePanelInput} data-testid={selectors.components.Annotations.annotationsChoosePanelInput}
/> />
)} )}
</> </>

View File

@ -26,7 +26,7 @@ export const OptionsPane = ({
const { data } = usePanelLatestData(panel, { withTransforms: true, withFieldConfig: false }, true); const { data } = usePanelLatestData(panel, { withTransforms: true, withFieldConfig: false }, true);
return ( return (
<div className={styles.wrapper} aria-label={selectors.components.PanelEditor.OptionsPane.content}> <div className={styles.wrapper} data-testid={selectors.components.PanelEditor.OptionsPane.content}>
{!isVizPickerOpen && ( {!isVizPickerOpen && (
<> <>
<div className={styles.vizButtonWrapper}> <div className={styles.vizButtonWrapper}>

View File

@ -111,9 +111,8 @@ export const OptionsPaneCategory = React.memo(
return ( return (
<div <div
className={boxStyles} className={boxStyles}
data-testid="options-category"
data-plugin-sandbox={sandboxId} data-plugin-sandbox={sandboxId}
aria-label={selectors.components.OptionsGroup.group(id)} data-testid={selectors.components.OptionsGroup.group(id)}
ref={ref} ref={ref}
> >
{/* disabling a11y rules here because there's a Button that handles keyboard interaction */} {/* disabling a11y rules here because there's a Button that handles keyboard interaction */}
@ -121,7 +120,7 @@ export const OptionsPaneCategory = React.memo(
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */} {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */}
<div className={headerStyles} onClick={onToggle}> <div className={headerStyles} onClick={onToggle}>
<Button <Button
aria-label={selectors.components.OptionsGroup.toggle(id)} data-testid={selectors.components.OptionsGroup.toggle(id)}
type="button" type="button"
fill="text" fill="text"
size="sm" size="sm"

View File

@ -244,7 +244,7 @@ describe('OptionsPaneOptions', () => {
scenario.render(); scenario.render();
const thresholdsSection = screen.getByLabelText(selectors.components.OptionsGroup.group('Thresholds')); const thresholdsSection = screen.getByTestId(selectors.components.OptionsGroup.group('Thresholds'));
expect( expect(
within(thresholdsSection).getByLabelText(OptionsPaneSelector.fieldLabel('Thresholds CustomThresholdOption')) within(thresholdsSection).getByLabelText(OptionsPaneSelector.fieldLabel('Thresholds CustomThresholdOption'))
).toBeInTheDocument(); ).toBeInTheDocument();

View File

@ -266,7 +266,7 @@ export class PanelEditorUnconnected extends PureComponent<Props> {
{panelPane} {panelPane}
<div <div
className={styles.tabsWrapper} className={styles.tabsWrapper}
aria-label={selectors.components.PanelEditor.DataPane.content} data-testid={selectors.components.PanelEditor.DataPane.content}
key="panel-editor-tabs" key="panel-editor-tabs"
> >
<PanelEditorTabs <PanelEditorTabs
@ -309,7 +309,7 @@ export class PanelEditorUnconnected extends PureComponent<Props> {
id="table-view" id="table-view"
value={tableViewEnabled} value={tableViewEnabled}
onClick={this.onToggleTableView} onClick={this.onToggleTableView}
aria-label={selectors.components.PanelEditor.toggleTableView} data-testid={selectors.components.PanelEditor.toggleTableView}
/> />
<RadioButtonGroup value={uiState.mode} options={displayModes} onChange={this.onDisplayModeChange} /> <RadioButtonGroup value={uiState.mode} options={displayModes} onChange={this.onDisplayModeChange} />
<DashNavTimeControls dashboard={dashboard} onChangeTimeZone={updateTimeZoneForSession} isOnCanvas={true} /> <DashNavTimeControls dashboard={dashboard} onChangeTimeZone={updateTimeZoneForSession} isOnCanvas={true} />
@ -442,7 +442,7 @@ export class PanelEditorUnconnected extends PureComponent<Props> {
<Page <Page
navModel={sectionNav} navModel={sectionNav}
pageNav={pageNav} pageNav={pageNav}
aria-label={selectors.components.PanelEditor.General.content} data-testid={selectors.components.PanelEditor.General.content}
layout={PageLayoutType.Custom} layout={PageLayoutType.Custom}
className={className} className={className}
> >

View File

@ -118,7 +118,7 @@ export function InspectJSONTab({ panel, dashboard, data, onClose }: Props) {
return ( return (
<div className={styles.wrap}> <div className={styles.wrap}>
<div className={styles.toolbar} aria-label={selectors.components.PanelInspector.Json.content}> <div className={styles.toolbar} data-testid={selectors.components.PanelInspector.Json.content}>
<Field label={t('dashboard.inspect-json.select-source', 'Select source')} className="flex-grow-1"> <Field label={t('dashboard.inspect-json.select-source', 'Select source')} className="flex-grow-1">
<Select <Select
inputId="select-source-dropdown" inputId="select-source-dropdown"

View File

@ -3981,16 +3981,16 @@ __metadata:
languageName: unknown languageName: unknown
linkType: soft linkType: soft
"@grafana/plugin-e2e@npm:1.1.1": "@grafana/plugin-e2e@npm:1.2.0":
version: 1.1.1 version: 1.2.0
resolution: "@grafana/plugin-e2e@npm:1.1.1" resolution: "@grafana/plugin-e2e@npm:1.2.0"
dependencies: dependencies:
semver: "npm:^7.5.4" semver: "npm:^7.5.4"
uuid: "npm:^9.0.1" uuid: "npm:^9.0.1"
yaml: "npm:^2.3.4" yaml: "npm:^2.3.4"
peerDependencies: peerDependencies:
"@playwright/test": ^1.41.2 "@playwright/test": ^1.41.2
checksum: 10/81d7732fc483bf2b2dd096e3a1efa5b12a32a67a79da9e92d8d502521928b2a75c735666f6b6c0de34a0d530243789ce5e12cac7a4655d425ce2e4f0033bbb11 checksum: 10/b7af12f214ef4daff0d917b6715fde181b29d72923d1d5c5a5d17e0f17084f23450be91e877d659aa3c2472002253d127d2465d80e25accb59154027228dbb8c
languageName: node languageName: node
linkType: hard linkType: hard
@ -18595,7 +18595,7 @@ __metadata:
"@grafana/lezer-logql": "npm:0.2.3" "@grafana/lezer-logql": "npm:0.2.3"
"@grafana/monaco-logql": "npm:^0.0.7" "@grafana/monaco-logql": "npm:^0.0.7"
"@grafana/o11y-ds-frontend": "workspace:*" "@grafana/o11y-ds-frontend": "workspace:*"
"@grafana/plugin-e2e": "npm:1.1.1" "@grafana/plugin-e2e": "npm:1.2.0"
"@grafana/prometheus": "workspace:*" "@grafana/prometheus": "workspace:*"
"@grafana/runtime": "workspace:*" "@grafana/runtime": "workspace:*"
"@grafana/saga-icons": "workspace:*" "@grafana/saga-icons": "workspace:*"