BrowseDashboards: Add (skipped) basic e2e tests to prepare for GA (#75917)

Add e2e tests for new Browse Dashboards UI
This commit is contained in:
Josh Hunt 2023-10-04 09:08:43 +00:00 committed by GitHub
parent 44fa0697ce
commit 40a41113aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 88 additions and 23 deletions

View File

@ -20,4 +20,48 @@ describe('Dashboard browse', () => {
e2e.components.Search.folderContent('General').should('be.visible'); e2e.components.Search.folderContent('General').should('be.visible');
e2e.components.Search.dashboardItem('E2E Test - Import Dashboard').should('be.visible'); e2e.components.Search.dashboardItem('E2E Test - Import Dashboard').should('be.visible');
}); });
it.skip('Manage Dashboards tests', () => {
e2e.flows.importDashboard(testDashboard, 1000, true);
e2e.pages.Dashboards.visit();
// Folders and dashboards should be visible
e2e.pages.BrowseDashboards.table.row('gdev dashboards').should('be.visible');
e2e.pages.BrowseDashboards.table.row('E2E Test - Import Dashboard').should('be.visible');
// gdev dashboards folder is collapsed - its content should not be visible
e2e.pages.BrowseDashboards.table.row('Alerting with TestData').should('not.exist');
// should click a folder and see it's children
e2e.pages.BrowseDashboards.table.row('gdev dashboards').find('[aria-label^="Expand folder"]').click();
e2e.pages.BrowseDashboards.table.row('Alerting with TestData').should('be.visible');
// Open the new folder drawer
cy.contains('button', 'New').click();
cy.contains('button', 'New folder').click();
// And create a new folder
e2e.pages.BrowseDashboards.NewFolderForm.nameInput().type('My new folder');
e2e.pages.BrowseDashboards.NewFolderForm.form().contains('button', 'Create').click();
e2e.components.Alert.alertV2('success').find('button[aria-label="Close alert"]').click();
cy.contains('h1', 'My new folder').should('be.visible');
// Delete the folder and expect to go back to the root
cy.contains('button', 'Folder actions').click();
cy.contains('button', 'Delete').click();
e2e.flows.confirmDelete();
cy.contains('h1', 'Dashboards').should('be.visible');
// Can collapse the gdev folder and delete the dashboard we imported
e2e.pages.BrowseDashboards.table.row('gdev dashboards').find('[aria-label^="Collapse folder"]').click();
e2e.pages.BrowseDashboards.table
.row('E2E Test - Import Dashboard')
.find('[type="checkbox"]')
.click({ force: true });
cy.contains('button', 'Delete').click();
e2e.flows.confirmDelete();
e2e.pages.BrowseDashboards.table.row('E2E Test - Import Dashboard').should('not.exist');
});
}); });

View File

@ -0,0 +1,6 @@
import { e2e } from '..';
export function confirmDelete() {
cy.get(`input[placeholder='Type "Delete" to confirm']`).type('Delete');
e2e.pages.ConfirmModal.delete().click();
}

View File

@ -15,6 +15,7 @@ export * from './setTimeRange';
export * from './importDashboard'; export * from './importDashboard';
export * from './importDashboards'; export * from './importDashboards';
export * from './userPreferences'; export * from './userPreferences';
export * from './confirmModal';
export { export {
VISUALIZATION_ALERT_LIST, VISUALIZATION_ALERT_LIST,

View File

@ -280,9 +280,14 @@ export const Pages = {
BrowseDashboards: { BrowseDashboards: {
table: { table: {
body: 'data-testid browse-dashboards-table', body: 'data-testid browse-dashboards-table',
row: (uid: string) => `data-testid ${uid} row`, row: (name: string) => `data-testid browse dashboards row ${name}`,
checkbox: (uid: string) => `data-testid ${uid} checkbox`, checkbox: (uid: string) => `data-testid ${uid} checkbox`,
}, },
NewFolderForm: {
form: 'data-testid new folder form',
nameInput: 'data-testid new-folder-name-input',
createButton: 'data-testid new-folder-create-button',
},
}, },
Search: { Search: {
url: '/?search=openn', url: '/?search=openn',

View File

@ -4,6 +4,7 @@ import React from 'react';
import { TestProvider } from 'test/helpers/TestProvider'; import { TestProvider } from 'test/helpers/TestProvider';
import { selectors } from '@grafana/e2e-selectors'; import { selectors } from '@grafana/e2e-selectors';
import { DashboardViewItem } from 'app/features/search/types';
import { wellFormedTree } from '../fixtures/dashboardsTreeItem.fixture'; import { wellFormedTree } from '../fixtures/dashboardsTreeItem.fixture';
@ -47,10 +48,10 @@ describe('browse-dashboards BrowseView', () => {
render(<BrowseView canSelect folderUID={undefined} width={WIDTH} height={HEIGHT} />); render(<BrowseView canSelect folderUID={undefined} width={WIDTH} height={HEIGHT} />);
await screen.findByText(folderA.item.title); await screen.findByText(folderA.item.title);
await expandFolder(folderA.item.uid); await expandFolder(folderA.item);
expect(screen.queryByText(folderA_folderA.item.title)).toBeInTheDocument(); expect(screen.queryByText(folderA_folderA.item.title)).toBeInTheDocument();
await collapseFolder(folderA.item.uid); await collapseFolder(folderA.item);
expect(screen.queryByText(folderA_folderA.item.title)).not.toBeInTheDocument(); expect(screen.queryByText(folderA_folderA.item.title)).not.toBeInTheDocument();
}); });
@ -69,8 +70,8 @@ describe('browse-dashboards BrowseView', () => {
await screen.findByText(folderA.item.title); await screen.findByText(folderA.item.title);
// First expand then click folderA // First expand then click folderA
await expandFolder(folderA.item.uid); await expandFolder(folderA.item);
await clickCheckbox(folderA.item.uid); await clickCheckbox(folderA.item);
// All the visible items in it should be checked now // All the visible items in it should be checked now
const directChildren = mockTree.filter((v) => v.item.kind !== 'ui' && v.item.parentUID === folderA.item.uid); const directChildren = mockTree.filter((v) => v.item.kind !== 'ui' && v.item.parentUID === folderA.item.uid);
@ -86,12 +87,12 @@ describe('browse-dashboards BrowseView', () => {
await screen.findByText(folderA.item.title); await screen.findByText(folderA.item.title);
// First expand then click folderA // First expand then click folderA
await expandFolder(folderA.item.uid); await expandFolder(folderA.item);
await clickCheckbox(folderA.item.uid); await clickCheckbox(folderA.item);
// When additional children are loaded (by expanding a folder), those items // When additional children are loaded (by expanding a folder), those items
// should also be selected // should also be selected
await expandFolder(folderA_folderB.item.uid); await expandFolder(folderA_folderB.item);
const grandchildren = mockTree.filter((v) => v.item.kind !== 'ui' && v.item.parentUID === folderA_folderB.item.uid); const grandchildren = mockTree.filter((v) => v.item.kind !== 'ui' && v.item.parentUID === folderA_folderB.item.uid);
@ -105,11 +106,11 @@ describe('browse-dashboards BrowseView', () => {
render(<BrowseView canSelect folderUID={undefined} width={WIDTH} height={HEIGHT} />); render(<BrowseView canSelect folderUID={undefined} width={WIDTH} height={HEIGHT} />);
await screen.findByText(folderA.item.title); await screen.findByText(folderA.item.title);
await expandFolder(folderA.item.uid); await expandFolder(folderA.item);
await expandFolder(folderA_folderB.item.uid); await expandFolder(folderA_folderB.item);
await clickCheckbox(folderA.item.uid); await clickCheckbox(folderA.item);
await clickCheckbox(folderA_folderB_dashbdB.item.uid); await clickCheckbox(folderA_folderB_dashbdB.item);
const itemCheckbox = screen.queryByTestId( const itemCheckbox = screen.queryByTestId(
selectors.pages.BrowseDashboards.table.checkbox(folderA_folderB_dashbdB.item.uid) selectors.pages.BrowseDashboards.table.checkbox(folderA_folderB_dashbdB.item.uid)
@ -129,10 +130,10 @@ describe('browse-dashboards BrowseView', () => {
render(<BrowseView canSelect={true} folderUID={undefined} width={WIDTH} height={HEIGHT} />); render(<BrowseView canSelect={true} folderUID={undefined} width={WIDTH} height={HEIGHT} />);
await screen.findByText(folderA.item.title); await screen.findByText(folderA.item.title);
await expandFolder(folderA.item.uid); await expandFolder(folderA.item);
await expandFolder(folderA_folderB.item.uid); await expandFolder(folderA_folderB.item);
await clickCheckbox(folderA_folderB_dashbdB.item.uid); await clickCheckbox(folderA_folderB_dashbdB.item);
const parentCheckbox = screen.queryByTestId( const parentCheckbox = screen.queryByTestId(
selectors.pages.BrowseDashboards.table.checkbox(folderA_folderB.item.uid) selectors.pages.BrowseDashboards.table.checkbox(folderA_folderB.item.uid)
@ -158,19 +159,19 @@ describe('browse-dashboards BrowseView', () => {
}); });
}); });
async function expandFolder(uid: string) { async function expandFolder(item: DashboardViewItem) {
const row = screen.getByTestId(selectors.pages.BrowseDashboards.table.row(uid)); const row = screen.getByTestId(selectors.pages.BrowseDashboards.table.row(item.title));
const expandButton = getByLabelText(row, /Expand folder/); const expandButton = getByLabelText(row, /Expand folder/);
await userEvent.click(expandButton); await userEvent.click(expandButton);
} }
async function collapseFolder(uid: string) { async function collapseFolder(item: DashboardViewItem) {
const row = screen.getByTestId(selectors.pages.BrowseDashboards.table.row(uid)); const row = screen.getByTestId(selectors.pages.BrowseDashboards.table.row(item.title));
const expandButton = getByLabelText(row, /Collapse folder/); const expandButton = getByLabelText(row, /Collapse folder/);
await userEvent.click(expandButton); await userEvent.click(expandButton);
} }
async function clickCheckbox(uid: string) { async function clickCheckbox(item: DashboardViewItem) {
const checkbox = screen.getByTestId(selectors.pages.BrowseDashboards.table.checkbox(uid)); const checkbox = screen.getByTestId(selectors.pages.BrowseDashboards.table.checkbox(item.uid));
await userEvent.click(checkbox); await userEvent.click(checkbox);
} }

View File

@ -190,7 +190,9 @@ function VirtualListRow({ index, style, data }: VirtualListRowProps) {
<div <div
{...row.getRowProps({ style })} {...row.getRowProps({ style })}
className={cx(styles.row, styles.bodyRow)} className={cx(styles.row, styles.bodyRow)}
data-testid={selectors.pages.BrowseDashboards.table.row(row.original.item.uid)} data-testid={selectors.pages.BrowseDashboards.table.row(
'title' in row.original.item ? row.original.item.title : row.original.item.uid
)}
> >
{row.cells.map((cell) => { {row.cells.map((cell) => {
const { key, ...cellProps } = cell.getCellProps(); const { key, ...cellProps } = cell.getCellProps();

View File

@ -1,5 +1,6 @@
import React from 'react'; import React from 'react';
import { selectors } from '@grafana/e2e-selectors';
import { Button, Input, Form, Field, HorizontalGroup } from '@grafana/ui'; import { Button, Input, Form, Field, HorizontalGroup } from '@grafana/ui';
import { Trans, t } from 'app/core/internationalization'; import { Trans, t } from 'app/core/internationalization';
@ -37,7 +38,11 @@ export function NewFolderForm({ onCancel, onConfirm }: Props) {
const fieldNameLabel = t('browse-dashboards.new-folder-form.name-label', 'Folder name'); const fieldNameLabel = t('browse-dashboards.new-folder-form.name-label', 'Folder name');
return ( return (
<Form defaultValues={initialFormModel} onSubmit={(form: FormModel) => onConfirm(form.folderName)}> <Form
defaultValues={initialFormModel}
onSubmit={(form: FormModel) => onConfirm(form.folderName)}
data-testid={selectors.pages.BrowseDashboards.NewFolderForm.form}
>
{({ register, errors }) => ( {({ register, errors }) => (
<> <>
<Field <Field
@ -46,6 +51,7 @@ export function NewFolderForm({ onCancel, onConfirm }: Props) {
error={errors.folderName && errors.folderName.message} error={errors.folderName && errors.folderName.message}
> >
<Input <Input
data-testid={selectors.pages.BrowseDashboards.NewFolderForm.nameInput}
id="folder-name-input" id="folder-name-input"
{...register('folderName', { {...register('folderName', {
required: translatedFolderNameRequiredPhrase, required: translatedFolderNameRequiredPhrase,