Tab: Improve accessible name (#89602)

* replace aria-label selector with data-testid

* fix unit tests

* fix e2e selectors

* fix last unit test

* fix e2e tests

* fix casing

* fix e2e test

* fix casing
This commit is contained in:
Ashley Harrison 2024-06-24 17:48:26 +01:00 committed by GitHub
parent 5a8eff096a
commit 7d8afd9578
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 63 additions and 68 deletions

View File

@ -17,7 +17,7 @@ describe('Public dashboards', () => {
e2e.pages.Dashboard.DashNav.shareButton().click();
// Select public dashboards tab
e2e.pages.ShareDashboardModal.PublicDashboard.Tab().click();
e2e.components.Tab.title('Public dashboard').click();
// Create button should be disabled
e2e.pages.ShareDashboardModal.PublicDashboard.CreateButton().should('be.disabled');
@ -78,7 +78,7 @@ describe('Public dashboards', () => {
// Select public dashboards tab
cy.intercept('GET', '/api/dashboards/uid/ZqZnVvFZz/public-dashboards').as('query-public-dashboard');
e2e.pages.ShareDashboardModal.PublicDashboard.Tab().click();
e2e.components.Tab.title('Public dashboard').click();
cy.wait('@query-public-dashboard');
e2e.pages.ShareDashboardModal.PublicDashboard.CopyUrlInput().should('exist');
@ -118,7 +118,7 @@ describe('Public dashboards', () => {
// Select public dashboards tab
cy.intercept('GET', '/api/dashboards/uid/ZqZnVvFZz/public-dashboards').as('query-public-dashboard');
e2e.pages.ShareDashboardModal.PublicDashboard.Tab().click();
e2e.components.Tab.title('Public dashboard').click();
cy.wait('@query-public-dashboard');
// save url before disabling public dashboard

View File

@ -13,7 +13,7 @@ describe('Create a public dashboard with template variables shows a template var
e2e.pages.Dashboard.DashNav.shareButton().click();
// Select public dashboards tab
e2e.pages.ShareDashboardModal.PublicDashboard.Tab().click();
e2e.components.Tab.title('Public dashboard').click();
// Warning Alert dashboard cannot be made public because it has template variables
e2e.pages.ShareDashboardModal.PublicDashboard.TemplateVariablesWarningAlert().should('be.visible');

View File

@ -17,7 +17,7 @@ describe.skip('Public dashboards', () => {
e2e.components.NavToolbar.shareDashboard().click();
// Select public dashboards tab
e2e.pages.ShareDashboardModal.PublicDashboardScene.Tab().click();
e2e.components.Tab.title('Public dashboard').click();
// Create button should be disabled
e2e.pages.ShareDashboardModal.PublicDashboard.CreateButton().should('be.disabled');
@ -78,7 +78,7 @@ describe.skip('Public dashboards', () => {
// Select public dashboards tab
cy.intercept('GET', '/api/dashboards/uid/ZqZnVvFZz/public-dashboards').as('query-public-dashboard');
e2e.pages.ShareDashboardModal.PublicDashboardScene.Tab().click();
e2e.components.Tab.title('Public dashboard').click();
cy.wait('@query-public-dashboard');
e2e.pages.ShareDashboardModal.PublicDashboard.CopyUrlInput().should('exist');
@ -118,7 +118,7 @@ describe.skip('Public dashboards', () => {
// Select public dashboards tab
cy.intercept('GET', '/api/dashboards/uid/ZqZnVvFZz/public-dashboards').as('query-public-dashboard');
e2e.pages.ShareDashboardModal.PublicDashboardScene.Tab().click();
e2e.components.Tab.title('Public dashboard').click();
cy.wait('@query-public-dashboard');
// save url before disabling public dashboard

View File

@ -13,7 +13,7 @@ describe('Create a public dashboard with template variables shows a template var
e2e.components.NavToolbar.shareDashboard().click();
// Select public dashboards tab
e2e.pages.ShareDashboardModal.PublicDashboardScene.Tab().click();
e2e.components.Tab.title('Public Dashboard').click();
// Warning Alert dashboard cannot be made public because it has template variables
e2e.pages.ShareDashboardModal.PublicDashboard.TemplateVariablesWarningAlert().should('be.visible');

View File

@ -25,7 +25,7 @@ describe('Snapshots', () => {
e2e.components.NavToolbar.shareDashboard().click();
// Select the snapshot tab
e2e.pages.ShareDashboardModal.SnapshotScene.Tab().click();
e2e.components.Tab.title('Snapshot').click();
// Publish snapshot
cy.intercept('POST', '/api/snapshots').as('save');

View File

@ -266,7 +266,7 @@ export const Components = {
},
},
Tab: {
title: (title: string) => `Tab ${title}`,
title: (title: string) => `data-testid Tab ${title}`,
active: () => '[class*="-activeTabStyle"]',
},
RefreshPicker: {

View File

@ -104,7 +104,7 @@ export const Pages = {
* @deprecated use components.TimeZonePicker.containerV2 from Grafana 8.3 instead
*/
timezone: 'Time zone picker select container',
title: 'Tab General',
title: 'General',
},
Annotations: {
List: {
@ -246,7 +246,6 @@ export const Pages = {
},
ShareDashboardModal: {
PublicDashboard: {
Tab: 'Tab Public dashboard',
WillBePublicCheckbox: 'data-testid public dashboard will be public checkbox',
LimitedDSCheckbox: 'data-testid public dashboard limited datasources checkbox',
CostIncreaseCheckbox: 'data-testid public dashboard cost may increase checkbox',
@ -271,12 +270,8 @@ export const Pages = {
ReshareLink: 'data-testid public dashboard reshare link button',
},
},
PublicDashboardScene: {
Tab: 'Tab Public Dashboard',
},
SnapshotScene: {
url: (key: string) => `/dashboard/snapshot/${key}`,
Tab: 'Tab Snapshot',
PublishSnapshot: 'data-testid publish snapshot button',
CopyUrlButton: 'data-testid snapshot copy url button',
CopyUrlInput: 'data-testid snapshot copy url input',

View File

@ -43,9 +43,9 @@ export const Tab = React.forwardRef<HTMLElement, TabProps>(
const commonProps = {
className: linkClass,
'data-testid': selectors.components.Tab.title(label),
...otherProps,
onClick: onChangeTab,
'aria-label': otherProps['aria-label'] || selectors.components.Tab.title(label),
role: 'tab',
'aria-selected': active,
};

View File

@ -171,7 +171,7 @@ describe('contact points', () => {
}
// check buttons in Notification Templates
const notificationTemplatesTab = screen.getByRole('tab', { name: 'Tab Notification Templates' });
const notificationTemplatesTab = screen.getByRole('tab', { name: 'Notification Templates' });
await userEvent.click(notificationTemplatesTab);
expect(screen.getByRole('link', { name: 'Add notification template' })).toHaveAttribute('aria-disabled', 'true');
});
@ -388,7 +388,7 @@ describe('contact points', () => {
expect(viewProvisioned).not.toBeDisabled();
// check buttons in Notification Templates
const notificationTemplatesTab = screen.getByRole('tab', { name: 'Tab Notification Templates' });
const notificationTemplatesTab = screen.getByRole('tab', { name: 'Notification Templates' });
await userEvent.click(notificationTemplatesTab);
expect(screen.queryByRole('link', { name: 'Add notification template' })).not.toBeInTheDocument();
});

View File

@ -200,9 +200,9 @@ describe('browse-dashboards BrowseDashboardsPage', () => {
render(<BrowseDashboardsPage {...props} />);
expect(await screen.findByRole('heading', { name: 'Dashboards' })).toBeInTheDocument();
expect(screen.queryByRole('tab', { name: 'Tab Dashboards' })).not.toBeInTheDocument();
expect(screen.queryByRole('tab', { name: 'Tab Panels' })).not.toBeInTheDocument();
expect(screen.queryByRole('tab', { name: 'Tab Alert rules' })).not.toBeInTheDocument();
expect(screen.queryByRole('tab', { name: 'Dashboards' })).not.toBeInTheDocument();
expect(screen.queryByRole('tab', { name: 'Panels' })).not.toBeInTheDocument();
expect(screen.queryByRole('tab', { name: 'Alert rules' })).not.toBeInTheDocument();
});
it('displays the filters and hides the actions initially', async () => {
@ -327,14 +327,14 @@ describe('browse-dashboards BrowseDashboardsPage', () => {
it('displays all the folder tabs and shows the "Dashboards" tab as selected', async () => {
render(<BrowseDashboardsPage {...props} />);
expect(await screen.findByRole('tab', { name: 'Tab Dashboards' })).toBeInTheDocument();
expect(await screen.findByRole('tab', { name: 'Tab Dashboards' })).toHaveAttribute('aria-selected', 'true');
expect(await screen.findByRole('tab', { name: 'Dashboards' })).toBeInTheDocument();
expect(await screen.findByRole('tab', { name: 'Dashboards' })).toHaveAttribute('aria-selected', 'true');
expect(await screen.findByRole('tab', { name: 'Tab Panels' })).toBeInTheDocument();
expect(await screen.findByRole('tab', { name: 'Tab Panels' })).toHaveAttribute('aria-selected', 'false');
expect(await screen.findByRole('tab', { name: 'Panels' })).toBeInTheDocument();
expect(await screen.findByRole('tab', { name: 'Panels' })).toHaveAttribute('aria-selected', 'false');
expect(await screen.findByRole('tab', { name: 'Tab Alert rules' })).toBeInTheDocument();
expect(await screen.findByRole('tab', { name: 'Tab Alert rules' })).toHaveAttribute('aria-selected', 'false');
expect(await screen.findByRole('tab', { name: 'Alert rules' })).toBeInTheDocument();
expect(await screen.findByRole('tab', { name: 'Alert rules' })).toHaveAttribute('aria-selected', 'false');
});
it('displays the filters and hides the actions initially', async () => {

View File

@ -115,14 +115,14 @@ describe('browse-dashboards BrowseFolderAlertingPage', () => {
it('displays all the folder tabs and shows the "Alert rules" tab as selected', async () => {
render(<BrowseFolderAlertingPage {...props} />);
expect(await screen.findByRole('tab', { name: 'Tab Dashboards' })).toBeInTheDocument();
expect(await screen.findByRole('tab', { name: 'Tab Dashboards' })).toHaveAttribute('aria-selected', 'false');
expect(await screen.findByRole('tab', { name: 'Dashboards' })).toBeInTheDocument();
expect(await screen.findByRole('tab', { name: 'Dashboards' })).toHaveAttribute('aria-selected', 'false');
expect(await screen.findByRole('tab', { name: 'Tab Panels' })).toBeInTheDocument();
expect(await screen.findByRole('tab', { name: 'Tab Panels' })).toHaveAttribute('aria-selected', 'false');
expect(await screen.findByRole('tab', { name: 'Panels' })).toBeInTheDocument();
expect(await screen.findByRole('tab', { name: 'Panels' })).toHaveAttribute('aria-selected', 'false');
expect(await screen.findByRole('tab', { name: 'Tab Alert rules' })).toBeInTheDocument();
expect(await screen.findByRole('tab', { name: 'Tab Alert rules' })).toHaveAttribute('aria-selected', 'true');
expect(await screen.findByRole('tab', { name: 'Alert rules' })).toBeInTheDocument();
expect(await screen.findByRole('tab', { name: 'Alert rules' })).toHaveAttribute('aria-selected', 'true');
});
it('displays the alert rules returned by the API', async () => {

View File

@ -117,14 +117,14 @@ describe('browse-dashboards BrowseFolderLibraryPanelsPage', () => {
it('displays all the folder tabs and shows the "Library panels" tab as selected', async () => {
render(<BrowseFolderLibraryPanelsPage {...props} />);
expect(await screen.findByRole('tab', { name: 'Tab Dashboards' })).toBeInTheDocument();
expect(await screen.findByRole('tab', { name: 'Tab Dashboards' })).toHaveAttribute('aria-selected', 'false');
expect(await screen.findByRole('tab', { name: 'Dashboards' })).toBeInTheDocument();
expect(await screen.findByRole('tab', { name: 'Dashboards' })).toHaveAttribute('aria-selected', 'false');
expect(await screen.findByRole('tab', { name: 'Tab Panels' })).toBeInTheDocument();
expect(await screen.findByRole('tab', { name: 'Tab Panels' })).toHaveAttribute('aria-selected', 'true');
expect(await screen.findByRole('tab', { name: 'Panels' })).toBeInTheDocument();
expect(await screen.findByRole('tab', { name: 'Panels' })).toHaveAttribute('aria-selected', 'true');
expect(await screen.findByRole('tab', { name: 'Tab Alert rules' })).toBeInTheDocument();
expect(await screen.findByRole('tab', { name: 'Tab Alert rules' })).toHaveAttribute('aria-selected', 'false');
expect(await screen.findByRole('tab', { name: 'Alert rules' })).toBeInTheDocument();
expect(await screen.findByRole('tab', { name: 'Alert rules' })).toHaveAttribute('aria-selected', 'false');
});
it('displays the library panels returned by the API', async () => {

View File

@ -33,7 +33,7 @@ describe('SaveDashboardDrawer', () => {
expect(await screen.findByText('Save dashboard')).toBeInTheDocument();
expect(screen.queryByTestId(selectors.pages.SaveDashboardModal.saveTimerange)).not.toBeInTheDocument();
expect(screen.getByText('No changes to save')).toBeInTheDocument();
expect(screen.queryByLabelText('Tab Changes')).not.toBeInTheDocument();
expect(screen.queryByRole('tab', { name: /Changes/ })).not.toBeInTheDocument();
});
it('When there are no changes', async () => {
@ -61,11 +61,11 @@ describe('SaveDashboardDrawer', () => {
expect(await screen.findByText('Save dashboard')).toBeInTheDocument();
expect(screen.queryByTestId(selectors.pages.SaveDashboardModal.saveTimerange)).toBeInTheDocument();
expect(screen.queryByLabelText('Tab Changes')).not.toBeInTheDocument();
expect(screen.queryByRole('tab', { name: /Changes/ })).not.toBeInTheDocument();
await userEvent.click(screen.getByTestId(selectors.pages.SaveDashboardModal.saveTimerange));
expect(await screen.findByLabelText('Tab Changes')).toBeInTheDocument();
expect(await screen.findByRole('tab', { name: /Changes/ })).toBeInTheDocument();
});
it('When refresh changed show save refresh option', async () => {
@ -94,11 +94,11 @@ describe('SaveDashboardDrawer', () => {
expect(await screen.findByText('Save dashboard')).toBeInTheDocument();
expect(screen.getByTestId(selectors.pages.SaveDashboardModal.saveRefresh)).toBeInTheDocument();
expect(screen.queryByLabelText('Tab Changes')).not.toBeInTheDocument();
expect(screen.queryByRole('tab', { name: /Changes/ })).not.toBeInTheDocument();
await userEvent.click(screen.getByTestId(selectors.pages.SaveDashboardModal.saveRefresh));
expect(await screen.findByLabelText('Tab Changes')).toBeInTheDocument();
expect(await screen.findByRole('tab', { name: /Changes/ })).toBeInTheDocument();
});
it('Can show changes', async () => {
@ -108,7 +108,7 @@ describe('SaveDashboardDrawer', () => {
openAndRender();
await userEvent.click(await screen.findByLabelText('Tab Changes'));
await userEvent.click(await screen.findByRole('tab', { name: /Changes/ }));
expect(await screen.findByText('Full JSON diff')).toBeInTheDocument();
});

View File

@ -89,7 +89,7 @@ describe('LinksSettings', () => {
const linklessDashboard = createDashboardModelFixture({ links: [] });
setup(linklessDashboard);
const linksTab = screen.getByRole('tab', { name: 'Tab Links' });
const linksTab = screen.getByRole('tab', { name: 'Links' });
expect(linksTab).toBeInTheDocument();
expect(linksTab).toHaveAttribute('aria-selected', 'true');
expect(screen.getByRole('button', { name: 'Add dashboard link' })).toBeInTheDocument();

View File

@ -82,15 +82,15 @@ describe('ExploreQueryInspector', () => {
});
it('should render 4 Tabs if queryResponse has no error', () => {
setup();
expect(screen.getAllByLabelText(/tab/i)).toHaveLength(4);
expect(screen.getAllByRole('tab')).toHaveLength(4);
});
it('should render 5 Tabs if queryResponse has error', () => {
setup({ queryResponse: { error: 'Bad gateway' } });
expect(screen.getAllByLabelText(/tab/i)).toHaveLength(5);
expect(screen.getAllByRole('tab')).toHaveLength(5);
});
it('should display query data when click on expanding', () => {
setup();
fireEvent.click(screen.getByLabelText(/tab query/i));
fireEvent.click(screen.getByRole('tab', { name: /query/i }));
fireEvent.click(screen.getByText(/expand all/i));
expect(screen.getByText(/very unique test value/i)).toBeInTheDocument();
});
@ -134,7 +134,7 @@ describe('ExploreQueryInspector', () => {
},
});
fireEvent.click(screen.getByLabelText(/tab data/i));
fireEvent.click(screen.getByRole('tab', { name: /data/i }));
// assert series values are formatted to 3 digits (xx.x or x.xx)
expect(screen.getByText(/71.2/i)).toBeInTheDocument();
expect(screen.getByText(/72.3/i)).toBeInTheDocument();

View File

@ -67,7 +67,7 @@ const setup = (propOverrides?: Partial<RichHistoryProps>) => {
describe('RichHistory', () => {
it('should render tabs as defined', () => {
setup();
const tabs = screen.getAllByLabelText(/Tab*/);
const tabs = screen.getAllByRole('tab');
expect(tabs).toHaveLength(3);
expect(tabs[0]).toHaveTextContent('Query history');
expect(tabs[1]).toHaveTextContent('Starred');
@ -76,7 +76,7 @@ describe('RichHistory', () => {
it('should render defined default', () => {
setup();
const tabs = screen.getAllByLabelText(/Tab*/);
const tabs = screen.getAllByRole('tab');
expect(tabs[0].className).toMatch(/-*activeTabStyle/);
expect(tabs[1].className).not.toMatch(/-*activeTabStyle/);
});

View File

@ -65,7 +65,7 @@ export const assertQueryHistoryComment = async (expectedQueryComments: string[])
};
export const assertQueryHistoryTabIsSelected = (tabName: 'Query history' | 'Starred' | 'Settings') => {
expect(withinQueryHistory().getByRole('tab', { name: `Tab ${tabName}`, selected: true })).toBeInTheDocument();
expect(withinQueryHistory().getByRole('tab', { name: tabName, selected: true })).toBeInTheDocument();
};
export const assertDataSourceFilterVisibility = (visible: boolean) => {

View File

@ -38,14 +38,14 @@ export const openQueryLibrary = async () => {
await userEvent.click(button);
await waitFor(async () => {
screen.getByRole('tab', {
name: /tab query library/i,
name: /query library/i,
});
});
};
export const switchToQueryHistory = async () => {
const tab = screen.getByRole('tab', {
name: /tab query history/i,
name: /query history/i,
});
await userEvent.click(tab);
};
@ -71,7 +71,7 @@ export const closeQueryHistory = async () => {
};
export const switchToQueryHistoryTab = async (name: 'Settings' | 'Query History') => {
await userEvent.click(withinQueryHistory().getByRole('tab', { name: `Tab ${name}` }));
await userEvent.click(withinQueryHistory().getByRole('tab', { name }));
};
export const selectStarredTabFirst = async () => {

View File

@ -271,7 +271,7 @@ describe('Plugin details page', () => {
);
// Check if version information is available
expect(await findByRole('tab', { name: `Tab ${PluginTabLabels.VERSIONS}` })).toBeInTheDocument();
expect(await findByRole('tab', { name: PluginTabLabels.VERSIONS })).toBeInTheDocument();
// Check the column headers
expect(getByRole('columnheader', { name: /version/i })).toBeInTheDocument();
@ -430,7 +430,7 @@ describe('Plugin details page', () => {
});
// Wait for the install controls to be loaded
expect(await findByRole('tab', { name: `Tab ${PluginTabLabels.OVERVIEW}` })).toBeInTheDocument();
expect(await findByRole('tab', { name: PluginTabLabels.OVERVIEW })).toBeInTheDocument();
// Open the confirmation modal
await userEvent.click(getByRole('button', { name: /uninstall/i }));
@ -682,7 +682,7 @@ describe('Plugin details page', () => {
isPublished: false,
});
expect(await queryByRole('tab', { name: `Tab ${PluginTabLabels.VERSIONS}` })).not.toBeInTheDocument();
expect(await queryByRole('tab', { name: PluginTabLabels.VERSIONS })).not.toBeInTheDocument();
});
it('should not display update for plugins not published to gcom', async () => {
@ -694,7 +694,7 @@ describe('Plugin details page', () => {
isPublished: false,
});
expect(await findByRole('tab', { name: `Tab ${PluginTabLabels.OVERVIEW}` })).toBeInTheDocument();
expect(await findByRole('tab', { name: PluginTabLabels.OVERVIEW })).toBeInTheDocument();
expect(queryByRole('button', { name: /update/i })).not.toBeInTheDocument();
});
@ -708,7 +708,7 @@ describe('Plugin details page', () => {
isPublished: false,
});
expect(await findByRole('tab', { name: `Tab ${PluginTabLabels.OVERVIEW}` })).toBeInTheDocument();
expect(await findByRole('tab', { name: PluginTabLabels.OVERVIEW })).toBeInTheDocument();
expect(queryByRole('button', { name: /^install/i })).not.toBeInTheDocument();
});
@ -722,7 +722,7 @@ describe('Plugin details page', () => {
isPublished: false,
});
expect(await findByRole('tab', { name: `Tab ${PluginTabLabels.OVERVIEW}` })).toBeInTheDocument();
expect(await findByRole('tab', { name: PluginTabLabels.OVERVIEW })).toBeInTheDocument();
expect(queryByRole('button', { name: /uninstall/i })).not.toBeInTheDocument();
});
@ -812,7 +812,7 @@ describe('Plugin details page', () => {
it("should not display an install button for a plugin that isn't installed", async () => {
const { queryByRole, findByRole } = renderPluginDetails({ id, isInstalled: false });
expect(await findByRole('tab', { name: `Tab ${PluginTabLabels.OVERVIEW}` })).toBeInTheDocument();
expect(await findByRole('tab', { name: PluginTabLabels.OVERVIEW })).toBeInTheDocument();
expect(queryByRole('button', { name: /^install/i })).not.toBeInTheDocument();
});
@ -820,7 +820,7 @@ describe('Plugin details page', () => {
it('should not display an uninstall button for an already installed plugin', async () => {
const { queryByRole, findByRole } = renderPluginDetails({ id, isInstalled: true });
expect(await findByRole('tab', { name: `Tab ${PluginTabLabels.OVERVIEW}` })).toBeInTheDocument();
expect(await findByRole('tab', { name: PluginTabLabels.OVERVIEW })).toBeInTheDocument();
expect(queryByRole('button', { name: /uninstall/i })).not.toBeInTheDocument();
});
@ -828,7 +828,7 @@ describe('Plugin details page', () => {
it('should not display update or uninstall buttons for a plugin with update', async () => {
const { queryByRole, findByRole } = renderPluginDetails({ id, isInstalled: true, hasUpdate: true });
expect(await findByRole('tab', { name: `Tab ${PluginTabLabels.OVERVIEW}` })).toBeInTheDocument();
expect(await findByRole('tab', { name: PluginTabLabels.OVERVIEW })).toBeInTheDocument();
expect(queryByRole('button', { name: /update/i })).not.toBeInTheDocument();
expect(queryByRole('button', { name: /uninstall/i })).not.toBeInTheDocument();
@ -837,7 +837,7 @@ describe('Plugin details page', () => {
it('should not display an install button for enterprise plugins if license is valid', async () => {
const { findByRole, queryByRole } = renderPluginDetails({ id, isInstalled: false, isEnterprise: true });
expect(await findByRole('tab', { name: `Tab ${PluginTabLabels.OVERVIEW}` })).toBeInTheDocument();
expect(await findByRole('tab', { name: PluginTabLabels.OVERVIEW })).toBeInTheDocument();
expect(await queryByRole('button', { name: /^install/i })).not.toBeInTheDocument();
});
});

View File

@ -134,7 +134,7 @@ enum ExtensionPointComponentTabs {
Two = '2',
}
const _createTabName = (tab: ExtensionPointComponentTabs) => `Tab ${tab}`;
const _createTabName = (tab: ExtensionPointComponentTabs) => tab;
const _createTabContent = (tabId: ExtensionPointComponentId) => `this is settings for component ${tabId}`;
const generalTabName = 'General';