diff --git a/.yarn/cache/@playwright-test-npm-1.28.0-20a17c7d04-5b90a4fd7a.zip b/.yarn/cache/@playwright-test-npm-1.28.0-20a17c7d04-5b90a4fd7a.zip
deleted file mode 100644
index f8eb2b9edc92..000000000000
Binary files a/.yarn/cache/@playwright-test-npm-1.28.0-20a17c7d04-5b90a4fd7a.zip and /dev/null differ
diff --git a/.yarn/cache/@playwright-test-npm-1.36.2-0b5c09b329-659304e0bb.zip b/.yarn/cache/@playwright-test-npm-1.36.2-0b5c09b329-659304e0bb.zip
new file mode 100644
index 000000000000..4e11584d1c55
Binary files /dev/null and b/.yarn/cache/@playwright-test-npm-1.36.2-0b5c09b329-659304e0bb.zip differ
diff --git a/.yarn/cache/playwright-core-npm-1.28.0-9bd034478b-4bd13bf83b.zip b/.yarn/cache/playwright-core-npm-1.28.0-9bd034478b-4bd13bf83b.zip
deleted file mode 100644
index c5f6a0c3fb33..000000000000
Binary files a/.yarn/cache/playwright-core-npm-1.28.0-9bd034478b-4bd13bf83b.zip and /dev/null differ
diff --git a/.yarn/cache/playwright-core-npm-1.36.2-37b679cd9b-2193ce802e.zip b/.yarn/cache/playwright-core-npm-1.36.2-37b679cd9b-2193ce802e.zip
new file mode 100644
index 000000000000..c538ca249d08
Binary files /dev/null and b/.yarn/cache/playwright-core-npm-1.36.2-37b679cd9b-2193ce802e.zip differ
diff --git a/e2e/components/DataTable/DataTable-test.avt.e2e.js b/e2e/components/DataTable/DataTable-test.avt.e2e.js
new file mode 100644
index 000000000000..7259c55644d2
--- /dev/null
+++ b/e2e/components/DataTable/DataTable-test.avt.e2e.js
@@ -0,0 +1,373 @@
+/**
+ * Copyright IBM Corp. 2016, 2023
+ *
+ * This source code is licensed under the Apache-2.0 license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+'use strict';
+
+const { expect, test } = require('@playwright/test');
+const { visitStory } = require('../../test-utils/storybook');
+
+test.describe('DataTable @avt', () => {
+ test.describe('basic', () => {
+ test('default has no accessibility-checker violations', async ({
+ page,
+ }) => {
+ await visitStory(page, {
+ component: 'DataTable',
+ id: 'components-datatable-basic--default',
+ globals: {
+ theme: 'white',
+ },
+ });
+ await expect(page).toHaveNoACViolations(
+ 'components-datatable-basic--default'
+ );
+ });
+ test('xl with two lines has no accessibility-checker violations', async ({
+ page,
+ }) => {
+ await visitStory(page, {
+ component: 'DataTable',
+ id: 'components-datatable-basic--xl-with-two-lines',
+ globals: {
+ theme: 'white',
+ },
+ });
+ await expect(page).toHaveNoACViolations(
+ 'components-datatable-basic--xl-with-two-lines'
+ );
+ });
+ });
+
+ test.describe('batch actions', () => {
+ test('default has no accessibility-checker violations', async ({
+ page,
+ }) => {
+ await visitStory(page, {
+ component: 'DataTable',
+ id: 'components-datatable-batch-actions--default',
+ globals: {
+ theme: 'white',
+ },
+ });
+ await expect(page).toHaveNoACViolations(
+ 'components-datatable-batch-actions--default'
+ );
+ });
+ });
+
+ test.describe('dynamic', () => {
+ test('default has no accessibility-checker violations', async ({
+ page,
+ }) => {
+ await visitStory(page, {
+ component: 'DataTable',
+ id: 'components-datatable-dynamic--default',
+ globals: {
+ theme: 'white',
+ },
+ });
+ await expect(page).toHaveNoACViolations(
+ 'components-datatable-dynamic--default'
+ );
+ });
+
+ test('default keyboard navigation sequence', async ({ page }) => {
+ await visitStory(page, {
+ component: 'DataTable',
+ id: 'components-datatable-dynamic--default',
+ globals: {
+ theme: 'white',
+ },
+ });
+
+ await expect(page).toHaveNoACViolations(
+ 'components-datatable-dynamic--default'
+ );
+
+ // Start off by manually focusing the search input
+ await page.getByRole('searchbox').focus();
+ await expect(page.getByRole('searchbox')).toBeFocused();
+
+ // Navigate to the gear/settings button
+ await page.keyboard.press('Tab');
+ await expect(
+ page.getByRole('button', { name: 'Settings' })
+ ).toBeFocused();
+
+ // Navigate to the select all checkbox
+ await page.keyboard.press('Tab');
+ await expect(
+ page.getByRole('checkbox', { name: 'Select all rows' })
+ ).toBeFocused();
+
+ // Pressing enter on the select all checkbox shouldn't do anything
+ await page.keyboard.press('Enter');
+ await expect(
+ page.getByRole('checkbox', { name: 'Select all rows' })
+ ).not.toBeChecked();
+
+ // Pressing space should check the select all checkbox
+ await page.keyboard.press('Space');
+ await expect(
+ page.getByRole('checkbox', { name: 'Select all rows' })
+ ).toBeChecked();
+
+ // Every checkbox should be checked
+ for (const checkbox of await page.getByRole('checkbox').all()) {
+ await expect(checkbox).toBeChecked();
+ }
+
+ // Pressing space should uncheck the select all checkbox
+ await page.keyboard.press('Space');
+ await expect(
+ page.getByRole('checkbox', { name: 'Select all rows' })
+ ).not.toBeChecked();
+ // Every checkbox should no longer be checked
+ for (const checkbox of await page.getByRole('checkbox').all()) {
+ await expect(checkbox).not.toBeChecked();
+ }
+
+ // Navigate to the first expansion button
+ await page.keyboard.press('Tab');
+ await expect(
+ page.getByRole('button', { name: 'Expand current row' }).first()
+ ).toBeFocused();
+ // Expand the first row
+ await page.keyboard.press('Space');
+ await expect(
+ page.getByRole('heading', { name: 'Expandable row content' }).first()
+ ).toBeVisible();
+
+ // Navigate to the first row selection checkbox and check it
+ await page.keyboard.press('Tab');
+ await page.keyboard.press('Space');
+ await expect(page.getByText('1 item selected')).toBeVisible();
+
+ // Navigate backwards up into the batch action bar
+ await page.keyboard.press('Shift+Tab');
+ await page.keyboard.press('Shift+Tab');
+ await page.keyboard.press('Shift+Tab');
+ await page.keyboard.press('Shift+Tab');
+ await page.keyboard.press('Shift+Tab');
+ await page.keyboard.press('Shift+Tab');
+ await page.keyboard.press('Shift+Tab');
+ await page.keyboard.press('Shift+Tab');
+
+ await page
+ .getByRole('heading', { name: 'Expandable row content' })
+ .first()
+ .hover();
+ await expect(page).toHaveNoACViolations(
+ 'components-datatable-dynamic--default---with-batch-actions-open-and-row-expanded'
+ );
+ await expect(page.getByRole('button', { name: 'Delete' })).toBeFocused();
+
+ // Navigate forwards through the batch action buttons
+ await page.keyboard.press('Tab');
+ await expect(page.getByRole('button', { name: 'Save' })).toBeFocused();
+ await page.keyboard.press('Tab');
+ await expect(
+ page.getByRole('button', { name: 'Download' })
+ ).toBeFocused();
+ await page.keyboard.press('Tab');
+ await expect(page.getByRole('button', { name: 'Cancel' })).toBeFocused();
+ // Invoke the cancel button
+ await page.keyboard.press('Space');
+ await expect(page.getByText('1 item selected')).not.toBeVisible();
+ // Every checkbox should no longer be checked
+ for (const checkbox of await page.getByRole('checkbox').all()) {
+ await expect(checkbox).not.toBeChecked();
+ }
+ });
+ });
+
+ test.describe('expansion', () => {
+ test('default has no accessibility-checker violations', async ({
+ page,
+ }) => {
+ await visitStory(page, {
+ component: 'DataTable',
+ id: 'components-datatable-expansion--default',
+ globals: {
+ theme: 'white',
+ },
+ });
+ await expect(page).toHaveNoACViolations(
+ 'components-datatable-expansion--default'
+ );
+ });
+ test('batch expansion has no accessibility-checker violations', async ({
+ page,
+ }) => {
+ await visitStory(page, {
+ component: 'DataTable',
+ id: 'components-datatable-expansion--batch-expansion',
+ globals: {
+ theme: 'white',
+ },
+ });
+ await expect(page).toHaveNoACViolations(
+ 'components-datatable-expansion--batch-expansion'
+ );
+ });
+ });
+
+ test.describe('filtering', () => {
+ test('default has no accessibility-checker violations', async ({
+ page,
+ }) => {
+ await visitStory(page, {
+ component: 'DataTable',
+ id: 'components-datatable-filtering--default',
+ globals: {
+ theme: 'white',
+ },
+ });
+ await expect(page).toHaveNoACViolations(
+ 'components-datatable-filtering--default'
+ );
+ });
+ });
+
+ test.describe('selection', () => {
+ test('default has no accessibility-checker violations', async ({
+ page,
+ }) => {
+ await visitStory(page, {
+ component: 'DataTable',
+ id: 'components-datatable-selection--default',
+ globals: {
+ theme: 'white',
+ },
+ });
+ await expect(page).toHaveNoACViolations(
+ 'components-datatable-selection--default'
+ );
+ });
+ test('with-radio-expansion has no accessibility-checker violations', async ({
+ page,
+ }) => {
+ await visitStory(page, {
+ component: 'DataTable',
+ id: 'components-datatable-selection--with-radio-expansion',
+ globals: {
+ theme: 'white',
+ },
+ });
+ await expect(page).toHaveNoACViolations(
+ 'components-datatable-selection--with-radio-expansion'
+ );
+ });
+ test('with-selection-and-sorting has no accessibility-checker violations', async ({
+ page,
+ }) => {
+ await visitStory(page, {
+ component: 'DataTable',
+ id: 'components-datatable-selection--with-selection-and-sorting',
+ globals: {
+ theme: 'white',
+ },
+ });
+ await expect(page).toHaveNoACViolations(
+ 'components-datatable-selection--with-selection-and-sorting'
+ );
+ });
+ });
+
+ test.describe('skeleton', () => {
+ test('skeleton has no accessibility-checker violations', async ({
+ page,
+ }) => {
+ await visitStory(page, {
+ component: 'DataTable',
+ id: 'components-datatable-skeleton--skeleton',
+ globals: {
+ theme: 'white',
+ },
+ });
+ await expect(page).toHaveNoACViolations(
+ 'components-datatable-skeleton--skeleton'
+ );
+ });
+ });
+
+ test.describe('sorting', () => {
+ test('default has no accessibility-checker violations', async ({
+ page,
+ }) => {
+ await visitStory(page, {
+ component: 'DataTable',
+ id: 'components-datatable-sorting--default',
+ globals: {
+ theme: 'white',
+ },
+ });
+ await expect(page).toHaveNoACViolations(
+ 'components-datatable-sorting--default'
+ );
+ });
+ });
+
+ test.describe('toolbar', () => {
+ test('default has no accessibility-checker violations', async ({
+ page,
+ }) => {
+ await visitStory(page, {
+ component: 'DataTable',
+ id: 'components-datatable-toolbar--default',
+ globals: {
+ theme: 'white',
+ },
+ });
+ await expect(page).toHaveNoACViolations(
+ 'components-datatable-toolbar--default'
+ );
+ });
+ test('persistent-toolbar has no accessibility-checker violations', async ({
+ page,
+ }) => {
+ await visitStory(page, {
+ component: 'DataTable',
+ id: 'components-datatable-toolbar--persistent-toolbar',
+ globals: {
+ theme: 'white',
+ },
+ });
+ await expect(page).toHaveNoACViolations(
+ 'components-datatable-toolbar--persistent-toolbar'
+ );
+ });
+ test('small-persistent-toolbar has no accessibility-checker violations', async ({
+ page,
+ }) => {
+ await visitStory(page, {
+ component: 'DataTable',
+ id: 'components-datatable-toolbar--small-persistent-toolbar',
+ globals: {
+ theme: 'white',
+ },
+ });
+ await expect(page).toHaveNoACViolations(
+ 'components-datatable-toolbar--small-persistent-toolbar'
+ );
+ });
+ test('with-overflow-menu has no accessibility-checker violations', async ({
+ page,
+ }) => {
+ await visitStory(page, {
+ component: 'DataTable',
+ id: 'components-datatable-toolbar--with-overflow-menu',
+ globals: {
+ theme: 'white',
+ },
+ });
+ await expect(page).toHaveNoACViolations(
+ 'components-datatable-toolbar--with-overflow-menu'
+ );
+ });
+ });
+});
diff --git a/e2e/components/DataTable/DataTable-test.e2e.js b/e2e/components/DataTable/DataTable-test.e2e.js
index 0c20124d666d..2687d087996f 100644
--- a/e2e/components/DataTable/DataTable-test.e2e.js
+++ b/e2e/components/DataTable/DataTable-test.e2e.js
@@ -7,9 +7,9 @@
'use strict';
-const { expect, test } = require('@playwright/test');
+const { test } = require('@playwright/test');
const { themes } = require('../../test-utils/env');
-const { snapshotStory, visitStory } = require('../../test-utils/storybook');
+const { snapshotStory } = require('../../test-utils/storybook');
test.describe('DataTable', () => {
themes.forEach((theme) => {
@@ -127,15 +127,4 @@ test.describe('DataTable', () => {
});
});
});
-
- test('accessibility-checker @avt', async ({ page }) => {
- await visitStory(page, {
- component: 'DataTable',
- id: 'components-datatable-basic--default',
- globals: {
- theme: 'white',
- },
- });
- await expect(page).toHaveNoACViolations('DataTable');
- });
});
diff --git a/package.json b/package.json
index d1da3637b574..d38f331ea660 100644
--- a/package.json
+++ b/package.json
@@ -51,7 +51,7 @@
"@commitlint/config-conventional": "^17.0.0",
"@percy/cli": "^1.1.0",
"@percy/playwright": "^1.0.4",
- "@playwright/test": "^1.28.0",
+ "@playwright/test": "^1.36.2",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^14.0.0",
"@testing-library/user-event": "^14.4.3",
diff --git a/packages/react/src/components/DataTable/stories/DataTable-toolbar.stories.js b/packages/react/src/components/DataTable/stories/DataTable-toolbar.stories.js
index c04d223dfaab..a26d66719fd4 100644
--- a/packages/react/src/components/DataTable/stories/DataTable-toolbar.stories.js
+++ b/packages/react/src/components/DataTable/stories/DataTable-toolbar.stories.js
@@ -261,7 +261,7 @@ export const WithOverflowMenu = () => (
{header.header}
))}
-
+
diff --git a/packages/react/src/components/DataTable/stories/dynamic-content/DataTable-dynamic-content.stories.js b/packages/react/src/components/DataTable/stories/dynamic-content/DataTable-dynamic-content.stories.js
index f5668b6bfed5..83185d03e76f 100644
--- a/packages/react/src/components/DataTable/stories/dynamic-content/DataTable-dynamic-content.stories.js
+++ b/packages/react/src/components/DataTable/stories/dynamic-content/DataTable-dynamic-content.stories.js
@@ -116,77 +116,89 @@ export const Default = () => {
selectedRows,
getTableProps,
getTableContainerProps,
- }) => (
-
-
-
-
- Delete
-
-
- Save
-
-
- Download
-
-
-
-
-
-
- Add row
-
-
- Add header
-
-
-
-
-
-
-
-
-
- {headers.map((header, i) => (
-
- {header.header}
-
+ }) => {
+ const batchActionProps = getBatchActionProps();
+ return (
+
+
+
+
+ Delete
+
+
+ Save
+
+
+ Download
+
+
+
+
+
+
+ Add row
+
+
+ Add header
+
+
+
+
+
+
+
+
+
+ {headers.map((header, i) => (
+
+ {header.header}
+
+ ))}
+
+
+
+ {rows.map((row) => (
+
+
+
+ {row.cells.map((cell) => (
+ {cell.value}
+ ))}
+
+
+ Expandable row content
+ Description here
+
+
))}
-
-
-
- {rows.map((row) => (
-
-
-
- {row.cells.map((cell) => (
- {cell.value}
- ))}
-
-
- Expandable row content
- Description here
-
-
- ))}
-
-
-
- )}
+
+
+
+ );
+ }}
/>
);
}
@@ -273,99 +285,111 @@ export const Playground = (args) => {
selectedRows,
getTableProps,
getTableContainerProps,
- }) => (
-
-
-
-
- Delete
-
-
- Save
-
-
- Download
-
-
-
- {
- action('TableToolbarSearch - onChange')(evt);
- onInputChange(evt);
- }}
- />
-
- {
- action('handleOnRowAdd')(evt);
- this.handleOnRowAdd();
- }}>
- Add row
-
- {
- action('handleOnHeaderAdd')(evt);
- this.handleOnHeaderAdd();
- }}>
- Add header
-
-
-
-
-
-
-
-
- {args.radio ? (
- |
- ) : (
-
- )}
- {headers.map((header, i) => (
-
- {header.header}
-
+ }) => {
+ const batchActionProps = getBatchActionProps();
+ return (
+
+
+
+
+ Delete
+
+
+ Save
+
+
+ Download
+
+
+
+ {
+ action('TableToolbarSearch - onChange')(evt);
+ onInputChange(evt);
+ }}
+ />
+
+ {
+ action('handleOnRowAdd')(evt);
+ this.handleOnRowAdd();
+ }}>
+ Add row
+
+ {
+ action('handleOnHeaderAdd')(evt);
+ this.handleOnHeaderAdd();
+ }}>
+ Add header
+
+
+
+
+
+
+
+
+ {args.radio ? (
+ |
+ ) : (
+
+ )}
+ {headers.map((header, i) => (
+
+ {header.header}
+
+ ))}
+
+
+
+ {rows.map((row) => (
+
+
+
+ {row.cells.map((cell) => (
+ {cell.value}
+ ))}
+
+
+ Expandable row content
+ Description here
+
+
))}
-
-
-
- {rows.map((row) => (
-
-
-
- {row.cells.map((cell) => (
- {cell.value}
- ))}
-
-
- Expandable row content
- Description here
-
-
- ))}
-
-
-
- )}
+
+
+
+ );
+ }}
/>
);
}
diff --git a/packages/react/src/components/DataTable/stories/expansion/DataTable-expansion.stories.js b/packages/react/src/components/DataTable/stories/expansion/DataTable-expansion.stories.js
index 4103741697b2..1f7fb6d0943d 100644
--- a/packages/react/src/components/DataTable/stories/expansion/DataTable-expansion.stories.js
+++ b/packages/react/src/components/DataTable/stories/expansion/DataTable-expansion.stories.js
@@ -62,7 +62,7 @@ export const Default = () => (
-
+
{headers.map((header, i) => (
{header.header}
@@ -115,6 +115,7 @@ export const BatchExpansion = () => (
{headers.map((header, i) => (
diff --git a/packages/react/src/components/DataTableSkeleton/DataTableSkeleton.stories.js b/packages/react/src/components/DataTableSkeleton/DataTableSkeleton.stories.js
index 239ded4f1fb9..b27a1ea3b37b 100644
--- a/packages/react/src/components/DataTableSkeleton/DataTableSkeleton.stories.js
+++ b/packages/react/src/components/DataTableSkeleton/DataTableSkeleton.stories.js
@@ -29,7 +29,11 @@ export const Skeleton = () => {
const { ...rest } = props();
return (
-
+
);
@@ -38,7 +42,11 @@ export const Skeleton = () => {
export const Playground = (args) => {
return (
-
+
);
diff --git a/yarn.lock b/yarn.lock
index dae9f5f78657..922d8cf350e8 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5041,15 +5041,19 @@ __metadata:
languageName: node
linkType: hard
-"@playwright/test@npm:^1.28.0":
- version: 1.28.0
- resolution: "@playwright/test@npm:1.28.0"
+"@playwright/test@npm:^1.36.2":
+ version: 1.36.2
+ resolution: "@playwright/test@npm:1.36.2"
dependencies:
"@types/node": "*"
- playwright-core: 1.28.0
+ fsevents: 2.3.2
+ playwright-core: 1.36.2
+ dependenciesMeta:
+ fsevents:
+ optional: true
bin:
playwright: cli.js
- checksum: 5b90a4fd7a30e989f0b7ff97201eb3ab91d56b93ac5cd020ca6e36cd90a0f9386770214375b6c50471def75cbe0e7219f77f2c126d5d31655c5228bd16ab4f1a
+ checksum: 659304e0bbbafb2fa36395fbd8bd2c5db2b7791bbb55fa62409946ec7ec726cf8fff89f2b8a1a74fe831bf50a8780a37a5322a1251a6f7db2a9220a57ac408f0
languageName: node
linkType: hard
@@ -10556,7 +10560,7 @@ __metadata:
"@commitlint/config-conventional": ^17.0.0
"@percy/cli": ^1.1.0
"@percy/playwright": ^1.0.4
- "@playwright/test": ^1.28.0
+ "@playwright/test": ^1.36.2
"@testing-library/jest-dom": ^5.16.5
"@testing-library/react": ^14.0.0
"@testing-library/user-event": ^14.4.3
@@ -15809,7 +15813,7 @@ __metadata:
languageName: node
linkType: hard
-"fsevents@^2.3.2, fsevents@~2.3.2":
+"fsevents@^2.3.2, fsevents@npm:2.3.2, fsevents@~2.3.2":
version: 2.3.2
resolution: "fsevents@npm:2.3.2"
dependencies:
@@ -15819,7 +15823,7 @@ __metadata:
languageName: node
linkType: hard
-"fsevents@patch:fsevents@^2.3.2#~builtin, fsevents@patch:fsevents@~2.3.2#~builtin":
+"fsevents@patch:fsevents@2.3.2#~builtin, fsevents@patch:fsevents@^2.3.2#~builtin, fsevents@patch:fsevents@~2.3.2#~builtin":
version: 2.3.2
resolution: "fsevents@patch:fsevents@npm%3A2.3.2#~builtin::version=2.3.2&hash=df0bf1"
dependencies:
@@ -24175,12 +24179,12 @@ __metadata:
languageName: node
linkType: hard
-"playwright-core@npm:1.28.0":
- version: 1.28.0
- resolution: "playwright-core@npm:1.28.0"
+"playwright-core@npm:1.36.2":
+ version: 1.36.2
+ resolution: "playwright-core@npm:1.36.2"
bin:
- playwright: cli.js
- checksum: 4bd13bf83bca37f239f1573fcad7f3b559b3b5e28925f57fa66055446b2aef90c4403f9dbb4a9c34f6bd03a2461e61c97eb7fe5faed6b88f027c0bc3727cd096
+ playwright-core: cli.js
+ checksum: 2193ce802ef93c28b9b5e11a0b1d7b60778c686015659978d1cbf0eb9cda2cdc85ec5575b887c1346e9d161cc2805bf27638d76a2f7f857dffeae968e6ceffcd
languageName: node
linkType: hard