;
+
+export const CadForTest = ({
+ ...props
+}: CardForTestProps) => (
+
+
+
+ This is a card body.
+
+
+
+
+
+
+
+);
+
+export const CadWithScrollableForTest = ({
+ ...props
+}: CardForTestProps) => (
+
+
+
+
+ Hello! I'm scrollable card.
+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo
+ ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis
+ dis parturient montes, nascetur ridiculus mus. Donec quam felis,
+ ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa
+ quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget,
+ arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo.
+ Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras
+ dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend
+ tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac,
+ enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus.
+ Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean
+ imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper
+ ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus
+ eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing
+ sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar,
+ hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus.
+
+
+
+
+
+
+
+
+);
+
+export const CardOnlyWithBodyForTest = ({
+ ...props
+}: CardForTestProps) => (
+
+
+
+ This is a card body.
+
+
+
+
+);
diff --git a/src/components/Card/__tests__/Card.test.jsx b/src/components/Card/__tests__/Card.test.jsx
deleted file mode 100644
index 561ba88b9..000000000
--- a/src/components/Card/__tests__/Card.test.jsx
+++ /dev/null
@@ -1,57 +0,0 @@
-import React from 'react';
-import {
- render,
- within,
-} from '@testing-library/react';
-import { feedbackColorPropTest } from '../../../../tests/jest/propTests/feedbackColorPropTest';
-import { raisedPropTest } from '../../../../tests/jest/propTests/raisedPropTest';
-import { ScrollView } from '../../ScrollView';
-import { Card } from '../Card';
-import { CardBody } from '../CardBody';
-import { CardFooter } from '../CardFooter';
-import { densePropTest } from '../../../../tests/jest/propTests/densePropTest';
-
-const mandatoryProps = {
- children: card body content ,
-};
-
-describe('rendering', () => {
- it.each([
- [
- {
- children: [
- card body content ,
- card footer content ,
- ],
- },
- (rootElement) => {
- expect(within(rootElement).getByText('card body content'));
- expect(within(rootElement).getByText('card footer content'));
- },
- ],
- [
- { children: scroll view content },
- (rootElement) => expect(within(rootElement).getByText('scroll view content')),
- ],
- ...feedbackColorPropTest,
- ...densePropTest('Root'),
- [
- { disabled: true },
- (rootElement) => expect(rootElement).toHaveClass('isRootDisabled'),
- ],
- [
- { disabled: false },
- (rootElement) => expect(rootElement).not.toHaveClass('isRootDisabled'),
- ],
- ...raisedPropTest,
- ])('renders with props: "%s"', (testedProps, assert) => {
- const dom = render((
-
- ));
-
- assert(dom.container.firstChild);
- });
-});
diff --git a/src/components/Card/__tests__/CardBody.test.jsx b/src/components/Card/__tests__/CardBody.test.jsx
deleted file mode 100644
index 3fe4a34c0..000000000
--- a/src/components/Card/__tests__/CardBody.test.jsx
+++ /dev/null
@@ -1,28 +0,0 @@
-import React from 'react';
-import {
- render,
- within,
-} from '@testing-library/react';
-import { CardBody } from '../CardBody';
-
-const defaultProps = {
- children: 'content',
-};
-
-describe('rendering', () => {
- it.each([
- [
- { children: content text
},
- (rootElement) => expect(within(rootElement).getByText('content text')),
- ],
- ])('renders with props: "%s"', (testedProps, assert) => {
- const dom = render((
-
- ));
-
- assert(dom.container.firstChild);
- });
-});
diff --git a/src/components/Card/__tests__/CardFooter.test.jsx b/src/components/Card/__tests__/CardFooter.test.jsx
deleted file mode 100644
index 2949230ce..000000000
--- a/src/components/Card/__tests__/CardFooter.test.jsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import React from 'react';
-import {
- render,
- within,
-} from '@testing-library/react';
-import { childrenEmptyPropTest } from '../../../../tests/jest/propTests/childrenEmptyPropTest';
-import { CardFooter } from '../CardFooter';
-
-const defaultProps = {
- children: 'content',
-};
-
-describe('rendering', () => {
- it.each([
- [
- { children: content text
},
- (rootElement) => expect(within(rootElement).getByText('content text')),
- ],
- ...childrenEmptyPropTest,
- ])('renders with props: "%s"', (testedProps, assert) => {
- const dom = render((
-
- ));
-
- assert(dom.container.firstChild);
- });
-});
diff --git a/src/components/Card/__tests__/_propTests/densePropTest.ts b/src/components/Card/__tests__/_propTests/densePropTest.ts
new file mode 100644
index 000000000..94ddc97a9
--- /dev/null
+++ b/src/components/Card/__tests__/_propTests/densePropTest.ts
@@ -0,0 +1,12 @@
+import type { PropTests } from '../../../../../tests/playwright/types';
+
+export const densePropTest: PropTests = [
+ {
+ name: 'dense:boolean=true',
+ props: { dense: true },
+ },
+ {
+ name: 'dense:boolean=false',
+ props: { dense: false },
+ },
+];
diff --git a/src/components/Paper/__tests__/Paper.spec.tsx b/src/components/Paper/__tests__/Paper.spec.tsx
new file mode 100644
index 000000000..a75929e2e
--- /dev/null
+++ b/src/components/Paper/__tests__/Paper.spec.tsx
@@ -0,0 +1,64 @@
+import React from 'react';
+import {
+ expect,
+ test,
+} from '@playwright/experimental-ct-react';
+import {
+ mixPropTests,
+ propTests,
+} from '../../../../tests/playwright';
+import { PaperForTest } from './Paper.story';
+import { mutedPropTest } from './_propTests/mutedPropTest';
+
+test.describe('Paper', () => {
+ test.describe('visual', () => {
+ [
+ ...propTests.defaultComponentPropTest,
+ ...mixPropTests([
+ mutedPropTest,
+ propTests.raisedPropTest,
+ ]),
+ ].forEach(({
+ name,
+ onBeforeTest,
+ onBeforeSnapshot,
+ props,
+ }) => {
+ test(name, async ({
+ mount,
+ page,
+ }) => {
+ if (onBeforeTest) {
+ await onBeforeTest(page);
+ }
+
+ const component = await mount(
+ ,
+ );
+
+ if (onBeforeSnapshot) {
+ await onBeforeSnapshot(page, component);
+ }
+
+ const screenshot = await component.screenshot();
+ expect(screenshot).toMatchSnapshot();
+ });
+ });
+ });
+
+ test.describe('non-visual', () => {
+ test('id', async ({ mount }) => {
+ const id = 'test-id';
+
+ const component = await mount(
+ ,
+ );
+
+ await expect(component.locator(`div[id=${id}]`)).toHaveAttribute('id', id);
+ });
+ });
+});
diff --git a/src/components/Paper/__tests__/Paper.spec.tsx-snapshots/Paper-visual-defaultComponentProps-object-1-chromium-linux.png b/src/components/Paper/__tests__/Paper.spec.tsx-snapshots/Paper-visual-defaultComponentProps-object-1-chromium-linux.png
new file mode 100644
index 000000000..f80640425
Binary files /dev/null and b/src/components/Paper/__tests__/Paper.spec.tsx-snapshots/Paper-visual-defaultComponentProps-object-1-chromium-linux.png differ
diff --git a/src/components/Paper/__tests__/Paper.spec.tsx-snapshots/Paper-visual-muted-boolean-false-raised-boolean-false-1-chromium-linux.png b/src/components/Paper/__tests__/Paper.spec.tsx-snapshots/Paper-visual-muted-boolean-false-raised-boolean-false-1-chromium-linux.png
new file mode 100644
index 000000000..f80640425
Binary files /dev/null and b/src/components/Paper/__tests__/Paper.spec.tsx-snapshots/Paper-visual-muted-boolean-false-raised-boolean-false-1-chromium-linux.png differ
diff --git a/src/components/Paper/__tests__/Paper.spec.tsx-snapshots/Paper-visual-muted-boolean-false-raised-boolean-true-1-chromium-linux.png b/src/components/Paper/__tests__/Paper.spec.tsx-snapshots/Paper-visual-muted-boolean-false-raised-boolean-true-1-chromium-linux.png
new file mode 100644
index 000000000..72a4e7372
Binary files /dev/null and b/src/components/Paper/__tests__/Paper.spec.tsx-snapshots/Paper-visual-muted-boolean-false-raised-boolean-true-1-chromium-linux.png differ
diff --git a/src/components/Paper/__tests__/Paper.spec.tsx-snapshots/Paper-visual-muted-boolean-true-raised-boolean-false-1-chromium-linux.png b/src/components/Paper/__tests__/Paper.spec.tsx-snapshots/Paper-visual-muted-boolean-true-raised-boolean-false-1-chromium-linux.png
new file mode 100644
index 000000000..de753b904
Binary files /dev/null and b/src/components/Paper/__tests__/Paper.spec.tsx-snapshots/Paper-visual-muted-boolean-true-raised-boolean-false-1-chromium-linux.png differ
diff --git a/src/components/Paper/__tests__/Paper.spec.tsx-snapshots/Paper-visual-muted-boolean-true-raised-boolean-true-1-chromium-linux.png b/src/components/Paper/__tests__/Paper.spec.tsx-snapshots/Paper-visual-muted-boolean-true-raised-boolean-true-1-chromium-linux.png
new file mode 100644
index 000000000..1a9829e12
Binary files /dev/null and b/src/components/Paper/__tests__/Paper.spec.tsx-snapshots/Paper-visual-muted-boolean-true-raised-boolean-true-1-chromium-linux.png differ
diff --git a/src/components/Paper/__tests__/Paper.story.tsx b/src/components/Paper/__tests__/Paper.story.tsx
new file mode 100644
index 000000000..c1176686f
--- /dev/null
+++ b/src/components/Paper/__tests__/Paper.story.tsx
@@ -0,0 +1,16 @@
+import React from 'react';
+import type { HTMLAttributes } from 'react';
+import { Paper } from '..';
+
+// Types for story component will be improved when we have full TypeScript support
+type PaperForTestProps = HTMLAttributes;
+
+export const PaperForTest = ({
+ ...props
+}: PaperForTestProps) => (
+
+
+ This is a paper component.
+
+
+);
diff --git a/src/components/Paper/__tests__/Paper.test.jsx b/src/components/Paper/__tests__/Paper.test.jsx
deleted file mode 100644
index 83abd0cd0..000000000
--- a/src/components/Paper/__tests__/Paper.test.jsx
+++ /dev/null
@@ -1,38 +0,0 @@
-import React from 'react';
-import {
- render,
- within,
-} from '@testing-library/react';
-import { raisedPropTest } from '../../../../tests/jest/propTests/raisedPropTest';
-import { Paper } from '../Paper';
-
-const defaultProps = {
- children: 'sample text',
-};
-
-describe('rendering', () => {
- it.each([
- [
- { children: content text
},
- (rootElement) => expect(within(rootElement).getByText('content text')),
- ],
- [
- { muted: true },
- (rootElement) => expect(rootElement).toHaveClass('isRootMuted'),
- ],
- [
- { muted: false },
- (rootElement) => expect(rootElement).not.toHaveClass('isRootMuted'),
- ],
- ...raisedPropTest,
- ])('renders with props: "%s"', (testedProps, assert) => {
- const dom = render((
-
- ));
-
- assert(dom.container.firstChild);
- });
-});
diff --git a/src/components/Paper/__tests__/_propTests/mutedPropTest.ts b/src/components/Paper/__tests__/_propTests/mutedPropTest.ts
new file mode 100644
index 000000000..939be35e7
--- /dev/null
+++ b/src/components/Paper/__tests__/_propTests/mutedPropTest.ts
@@ -0,0 +1,16 @@
+import type { PropTests } from '../../../../../tests/playwright/types';
+
+export const mutedPropTest: PropTests = [
+ {
+ name: 'muted:boolean=true',
+ props: {
+ muted: true,
+ },
+ },
+ {
+ name: 'muted:boolean=false',
+ props: {
+ muted: false,
+ },
+ },
+];
diff --git a/src/components/Table/__tests__/Table.spec.tsx b/src/components/Table/__tests__/Table.spec.tsx
new file mode 100644
index 000000000..323f83c95
--- /dev/null
+++ b/src/components/Table/__tests__/Table.spec.tsx
@@ -0,0 +1,226 @@
+import React from 'react';
+import {
+ expect,
+ test,
+} from '@playwright/experimental-ct-react';
+import { propTests } from '../../../../tests/playwright';
+import { TableForTest } from './Table.story';
+import { sortPropTest } from './_propTests/sortPropTest';
+
+const baseColumns = [
+ {
+ label: 'id',
+ name: 'id',
+ },
+ {
+ isSortable: true,
+ label: 'column2',
+ name: 'column2',
+ },
+ {
+ label: 'column3',
+ name: 'column3',
+ },
+];
+
+const baseRows = [
+ {
+ column2: 2,
+ column3: 3,
+ id: 1,
+ },
+ {
+ column2: 3,
+ column3: 1,
+ id: 2,
+ },
+ {
+ column2: 1,
+ column3: 2,
+ id: 3,
+ },
+];
+
+test.describe('Table', () => {
+ test.describe('visual', () => {
+ [
+ ...propTests.defaultComponentPropTest,
+ ...sortPropTest,
+ ].forEach(({
+ name,
+ onBeforeTest,
+ onBeforeSnapshot,
+ props,
+ }) => {
+ test(name, async ({
+ mount,
+ page,
+ }) => {
+ if (onBeforeTest) {
+ await onBeforeTest(page);
+ }
+
+ const component = await mount(
+ ,
+ );
+
+ if (onBeforeSnapshot) {
+ await onBeforeSnapshot(page, component);
+ }
+
+ const screenshot = await component.screenshot();
+ expect(screenshot).toMatchSnapshot();
+ });
+ });
+ });
+
+ test.describe('non-visual', () => {
+ test('id', async ({ mount }) => {
+ const id = 'test-id';
+
+ const component = await mount(
+ ,
+ );
+
+ await expect(component).toHaveAttribute('id', id);
+ const headers = await component.getByRole('columnheader').all();
+ await Promise.all(
+ headers.map((header, index) => expect(header).toHaveAttribute('id', `${id}__headerCell__${baseColumns[index].name}`)),
+ );
+
+ const rows = await component.getByRole('row').all();
+ rows.shift();
+
+ const rowCells = await Promise.all(
+ rows.map((row) => row.getByRole('cell').all()),
+ );
+
+ const testChain = [];
+
+ rowCells.forEach((cells, rowIndex) => {
+ cells.forEach((cell, cellIndex) => testChain.push(
+ expect(cell).toHaveAttribute('id', `${id}__bodyCell__${baseColumns[cellIndex].name}__${baseRows[rowIndex].id}`),
+ ));
+ });
+
+ await Promise.allSettled(testChain);
+ });
+ });
+
+ test.describe('functionality', () => {
+ test('execute sort callback on click', async ({ mount }) => {
+ let called = false;
+ let columnName;
+ let directionName;
+
+ const component = await mount(
+ up,
+ column: 'column2',
+ descendingIcon: down
,
+ direction: 'asc',
+ onClick: (column: string, direction: string) => {
+ called = true;
+ columnName = column;
+ directionName = direction;
+ },
+ }}
+ />,
+ );
+
+ await component.getByText('up').click({ force: true });
+ expect(called).toBe(true);
+ expect(columnName).toBe('column2');
+ expect(directionName).toBe('asc');
+ });
+
+ test('execute sort callback on Enter press', async ({ mount }) => {
+ let called = false;
+ let columnName;
+ let directionName;
+
+ const component = await mount(
+ up,
+ column: 'column2',
+ descendingIcon: down
,
+ direction: 'asc',
+ onClick: (column: string, direction: string) => {
+ called = true;
+ columnName = column;
+ directionName = direction;
+ },
+ }}
+ />,
+ );
+
+ const button = component.getByRole('button');
+ await button.focus();
+ await button.press('Enter');
+ expect(called).toBe(true);
+ expect(columnName).toBe('column2');
+ expect(directionName).toBe('asc');
+ });
+
+ test('has correct tab focus order', async ({
+ mount,
+ page,
+ }) => {
+ const allSortableColumns = baseColumns.map((column) => ({
+ ...column,
+ isSortable: true,
+ }));
+
+ await mount(
+ up,
+ column: 'column2',
+ descendingIcon: down
,
+ direction: 'asc',
+ onClick: () => {},
+ }}
+ />,
+ );
+
+ const getFocusedElementParentInnerText = () => page.evaluate(() => {
+ const selector = document.activeElement;
+ return selector ? selector.parentElement.innerText : null;
+ });
+
+ await page.keyboard.press('Tab');
+ const label1 = await getFocusedElementParentInnerText();
+ expect(label1).toContain('id');
+
+ await page.keyboard.press('Tab');
+ const label2 = await getFocusedElementParentInnerText();
+ expect(label2).toContain('column2');
+
+ await page.keyboard.press('Tab');
+ const label3 = await getFocusedElementParentInnerText();
+ expect(label3).toContain('column3');
+
+ await page.keyboard.press('Shift+Tab');
+ const label4 = await getFocusedElementParentInnerText();
+ expect(label4).toContain('column2');
+
+ await page.keyboard.press('Shift+Tab');
+ const label5 = await getFocusedElementParentInnerText();
+ expect(label5).toContain('id');
+ });
+ });
+});
diff --git a/src/components/Table/__tests__/Table.spec.tsx-snapshots/Table-visual-defaultComponentProps-object-1-chromium-linux.png b/src/components/Table/__tests__/Table.spec.tsx-snapshots/Table-visual-defaultComponentProps-object-1-chromium-linux.png
new file mode 100644
index 000000000..9e752e31c
Binary files /dev/null and b/src/components/Table/__tests__/Table.spec.tsx-snapshots/Table-visual-defaultComponentProps-object-1-chromium-linux.png differ
diff --git a/src/components/Table/__tests__/Table.spec.tsx-snapshots/Table-visual-sort-shape-ascActive-1-chromium-linux.png b/src/components/Table/__tests__/Table.spec.tsx-snapshots/Table-visual-sort-shape-ascActive-1-chromium-linux.png
new file mode 100644
index 000000000..c9fa9d660
Binary files /dev/null and b/src/components/Table/__tests__/Table.spec.tsx-snapshots/Table-visual-sort-shape-ascActive-1-chromium-linux.png differ
diff --git a/src/components/Table/__tests__/Table.spec.tsx-snapshots/Table-visual-sort-shape-descActive-1-chromium-linux.png b/src/components/Table/__tests__/Table.spec.tsx-snapshots/Table-visual-sort-shape-descActive-1-chromium-linux.png
new file mode 100644
index 000000000..655c1a4aa
Binary files /dev/null and b/src/components/Table/__tests__/Table.spec.tsx-snapshots/Table-visual-sort-shape-descActive-1-chromium-linux.png differ
diff --git a/src/components/Table/__tests__/Table.story.tsx b/src/components/Table/__tests__/Table.story.tsx
new file mode 100644
index 000000000..f5f28435f
--- /dev/null
+++ b/src/components/Table/__tests__/Table.story.tsx
@@ -0,0 +1,56 @@
+import React from 'react';
+import type { HTMLAttributes } from 'react';
+import { Table } from '..';
+
+// Types for story component will be improved when we have full TypeScript support
+type TableForTestProps = HTMLAttributes;
+
+const baseColumns = [
+ {
+ label: 'ID',
+ name: 'id',
+ },
+ {
+ label: 'Name',
+ name: 'name',
+ },
+ {
+ format: (date: Date) => date.toLocaleDateString('en-GB'),
+ isSortable: true,
+ label: 'Date of birth',
+ name: 'dateOfBirth',
+ },
+];
+
+const baseRows = [
+ {
+ dateOfBirth: new Date(1940, 10, 9),
+ id: 1,
+ name: 'John Lennon',
+ },
+ {
+ dateOfBirth: new Date(1942, 6, 18),
+ id: 2,
+ name: 'Paul McCartney',
+ },
+ {
+ dateOfBirth: new Date(1943, 2, 25),
+ id: 3,
+ name: 'George Harrison',
+ },
+ {
+ dateOfBirth: new Date(1940, 7, 7),
+ id: 4,
+ name: 'Richard Starkey (Ringo Starr)',
+ },
+];
+
+export const TableForTest = ({
+ ...props
+}: TableForTestProps) => (
+
+);
diff --git a/src/components/Table/__tests__/Table.test.jsx b/src/components/Table/__tests__/Table.test.jsx
deleted file mode 100644
index f1e3b7427..000000000
--- a/src/components/Table/__tests__/Table.test.jsx
+++ /dev/null
@@ -1,132 +0,0 @@
-import React from 'react';
-import {
- render,
- screen,
- within,
-} from '@testing-library/react';
-import userEvent from '@testing-library/user-event';
-import { Table } from '../Table';
-
-const mandatoryProps = {
- columns: [
- {
- label: 'ID',
- name: 'id',
- },
- {
- format: (date) => new Date(date).toJSON(),
- isSortable: true,
- label: 'Date of birth',
- name: 'dateOfBirth',
- },
- ],
- rows: [
- {
- dateOfBirth: '2018-01-31',
- id: 'jan-novak',
- },
- {
- dateOfBirth: '2018-02-14',
- id: 111,
- },
- ],
-};
-
-describe('rendering', () => {
- it.each([
- [
- { columns: mandatoryProps.columns },
- (rootElement) => {
- expect(within(rootElement).getByText('ID'));
- expect(within(rootElement).getByText('Date of birth'));
- },
- ],
- [
- {
- id: 'id',
- sort: {
- ascendingIcon: ascending icon ,
- column: 'name',
- descendingIcon: descending icon ,
- direction: 'asc',
- onClick: () => {},
- },
- },
- (rootElement) => {
- expect(rootElement).toHaveAttribute('id', 'id');
- expect(within(rootElement).getByTestId('id__headerCell__id'));
- expect(within(rootElement).getByTestId('id__headerCell__dateOfBirth'));
- expect(within(rootElement).getByRole('button')).toHaveAttribute('id', 'id__headerCell__dateOfBirth__sortButton');
- expect(within(rootElement).getByTestId('id__headerCell__dateOfBirth'));
- expect(within(rootElement).getByTestId('id__bodyCell__id__jan-novak'));
- expect(within(rootElement).getByTestId('id__bodyCell__id__111'));
- expect(within(rootElement).getByTestId('id__bodyCell__dateOfBirth__jan-novak'));
- expect(within(rootElement).getByTestId('id__bodyCell__dateOfBirth__111'));
- },
- ],
- [
- { rows: mandatoryProps.rows },
- (rootElement) => {
- expect(within(rootElement).getByText('jan-novak'));
- expect(within(rootElement).getByText('2018-01-31T00:00:00.000Z'));
- expect(within(rootElement).getByText('111'));
- expect(within(rootElement).getByText('2018-02-14T00:00:00.000Z'));
- },
- ],
- [
- {
- sort: {
- ascendingIcon: ascending icon ,
- column: 'dateOfBirth',
- descendingIcon: descending icon ,
- direction: 'asc',
- onClick: () => {},
- },
- },
- (rootElement) => expect(within(rootElement).getByText('ascending icon')),
- ],
- [
- {
- sort: {
- ascendingIcon: ascending icon ,
- column: 'dateOfBirth',
- descendingIcon: descending icon ,
- direction: 'desc',
- onClick: () => {},
- },
- },
- (rootElement) => expect(within(rootElement).getByText('descending icon')),
- ],
- ])('renders with props: "%s"', (testedProps, assert) => {
- const dom = render((
-
- ));
-
- assert(dom.container.firstChild);
- });
-});
-
-describe('functionality', () => {
- it('calls onClick() on sorting button click', async () => {
- const spy = jest.fn();
- render((
- ascending icon,
- column: 'dateOfBirth',
- descendingIcon: descending icon ,
- direction: 'asc',
- onClick: spy,
- }}
- />
- ));
-
- await userEvent.click(screen.getByRole('button'));
- expect(spy).toHaveBeenCalled();
- expect(spy).toHaveBeenCalledWith('dateOfBirth', 'asc');
- });
-});
diff --git a/src/components/Table/__tests__/_propTests/sortPropTest.tsx b/src/components/Table/__tests__/_propTests/sortPropTest.tsx
new file mode 100644
index 000000000..e53c202e9
--- /dev/null
+++ b/src/components/Table/__tests__/_propTests/sortPropTest.tsx
@@ -0,0 +1,63 @@
+import React from 'react';
+import type { PropTests } from '../../../../../tests/playwright/types';
+
+const upIcon = (
+
+
+
+
+);
+
+const downIcon = (
+
+
+
+
+);
+
+export const sortPropTest: PropTests = [
+ {
+ name: 'sort:shape=ascActive',
+ props: {
+ sort: {
+ ascendingIcon: upIcon,
+ column: 'dateOfBirth',
+ descendingIcon: downIcon,
+ direction: 'asc',
+ },
+ },
+ },
+ {
+ name: 'sort:shape=descActive',
+ props: {
+ sort: {
+ ascendingIcon: upIcon,
+ column: 'dateOfBirth',
+ descendingIcon: downIcon,
+ direction: 'desc',
+ },
+ },
+ },
+];
diff --git a/src/components/Tabs/__tests__/TabItem.spec.tsx b/src/components/Tabs/__tests__/TabItem.spec.tsx
new file mode 100644
index 000000000..dbe09b6f3
--- /dev/null
+++ b/src/components/Tabs/__tests__/TabItem.spec.tsx
@@ -0,0 +1,126 @@
+import React from 'react';
+import {
+ expect,
+ test,
+} from '@playwright/experimental-ct-react';
+import {
+ propTests,
+ mixPropTests,
+} from '../../../../tests/playwright';
+import { TabItemForTest } from './TabItem.story';
+import { isActivePropTest } from './_propTests/tabItem/isActivePropTest';
+
+test.describe('TabItem', () => {
+ test.describe('visual', () => {
+ [
+ ...propTests.defaultComponentPropTest,
+ ...mixPropTests([
+ propTests.afterLabelPropTest,
+ isActivePropTest,
+ ]),
+ ...mixPropTests([
+ propTests.beforeLabelPropTest,
+ isActivePropTest,
+ ]),
+ ].forEach(({
+ name,
+ onBeforeTest,
+ onBeforeSnapshot,
+ props,
+ }) => {
+ test(name, async ({
+ mount,
+ page,
+ }) => {
+ if (onBeforeTest) {
+ await onBeforeTest(page);
+ }
+ const component = await mount(
+ ,
+ );
+ if (onBeforeSnapshot) {
+ await onBeforeSnapshot(page, component);
+ }
+ const screenshot = await component.screenshot();
+ expect(screenshot).toMatchSnapshot();
+ });
+ });
+ });
+
+ test.describe('non-visual', () => {
+ test('id', async ({ mount }) => {
+ const id = 'test-id';
+ const label = 'label';
+
+ const component = await mount(
+ ,
+ );
+
+ expect(component.locator(`li[id=${id}]`)).toBeDefined();
+ await expect(component.getByRole('link')).toHaveAttribute('id', `${id}__link`);
+ await expect(component.getByText(label)).toHaveAttribute('id', `${id}__label`);
+ });
+ });
+
+ test.describe('functionality', () => {
+ test('call on click callback', async ({ mount }) => {
+ let clicked = false;
+ const label = 'label';
+
+ const component = await mount(
+ {
+ clicked = true;
+ }}
+ />,
+ );
+
+ const link = component.getByRole('link');
+ await link.click({ force: true });
+ expect(clicked).toBe(true);
+ });
+
+ test('call on click callback when Enter pressed', async ({ mount }) => {
+ let clicked = false;
+ const label = 'label';
+
+ const component = await mount(
+ {
+ clicked = true;
+ }}
+ />,
+ );
+
+ const link = component.getByRole('link');
+ await link.focus();
+ await link.press('Enter');
+ expect(clicked).toBe(true);
+ });
+
+ test('calls native redirect when clicked on', async ({ mount }) => {
+ const testHref = '/test/custom/uri';
+
+ const component = await mount(
+ {}}
+ />,
+ );
+
+ const link = component.getByRole('link');
+ const page = component.page();
+ await Promise.all([
+ page.waitForURL(testHref),
+ link.click({ force: true }),
+ ]);
+
+ expect(page.url()).toContain(testHref);
+ });
+ });
+});
diff --git a/src/components/Tabs/__tests__/TabItem.spec.tsx-snapshots/TabItem-visual-afterLabel-node-isActive-boolean-false-1-chromium-linux.png b/src/components/Tabs/__tests__/TabItem.spec.tsx-snapshots/TabItem-visual-afterLabel-node-isActive-boolean-false-1-chromium-linux.png
new file mode 100644
index 000000000..6c1d96dfa
Binary files /dev/null and b/src/components/Tabs/__tests__/TabItem.spec.tsx-snapshots/TabItem-visual-afterLabel-node-isActive-boolean-false-1-chromium-linux.png differ
diff --git a/src/components/Tabs/__tests__/TabItem.spec.tsx-snapshots/TabItem-visual-afterLabel-node-isActive-boolean-true-1-chromium-linux.png b/src/components/Tabs/__tests__/TabItem.spec.tsx-snapshots/TabItem-visual-afterLabel-node-isActive-boolean-true-1-chromium-linux.png
new file mode 100644
index 000000000..da255a309
Binary files /dev/null and b/src/components/Tabs/__tests__/TabItem.spec.tsx-snapshots/TabItem-visual-afterLabel-node-isActive-boolean-true-1-chromium-linux.png differ
diff --git a/src/components/Tabs/__tests__/TabItem.spec.tsx-snapshots/TabItem-visual-beforeLabel-node-isActive-boolean-false-1-chromium-linux.png b/src/components/Tabs/__tests__/TabItem.spec.tsx-snapshots/TabItem-visual-beforeLabel-node-isActive-boolean-false-1-chromium-linux.png
new file mode 100644
index 000000000..63b6fd9fa
Binary files /dev/null and b/src/components/Tabs/__tests__/TabItem.spec.tsx-snapshots/TabItem-visual-beforeLabel-node-isActive-boolean-false-1-chromium-linux.png differ
diff --git a/src/components/Tabs/__tests__/TabItem.spec.tsx-snapshots/TabItem-visual-beforeLabel-node-isActive-boolean-true-1-chromium-linux.png b/src/components/Tabs/__tests__/TabItem.spec.tsx-snapshots/TabItem-visual-beforeLabel-node-isActive-boolean-true-1-chromium-linux.png
new file mode 100644
index 000000000..6ff60b89f
Binary files /dev/null and b/src/components/Tabs/__tests__/TabItem.spec.tsx-snapshots/TabItem-visual-beforeLabel-node-isActive-boolean-true-1-chromium-linux.png differ
diff --git a/src/components/Tabs/__tests__/TabItem.spec.tsx-snapshots/TabItem-visual-defaultComponentProps-object-1-chromium-linux.png b/src/components/Tabs/__tests__/TabItem.spec.tsx-snapshots/TabItem-visual-defaultComponentProps-object-1-chromium-linux.png
new file mode 100644
index 000000000..1a12d6cc0
Binary files /dev/null and b/src/components/Tabs/__tests__/TabItem.spec.tsx-snapshots/TabItem-visual-defaultComponentProps-object-1-chromium-linux.png differ
diff --git a/src/components/Tabs/__tests__/TabItem.story.tsx b/src/components/Tabs/__tests__/TabItem.story.tsx
new file mode 100644
index 000000000..06aaa3599
--- /dev/null
+++ b/src/components/Tabs/__tests__/TabItem.story.tsx
@@ -0,0 +1,24 @@
+import React from 'react';
+import type { HTMLAttributes } from 'react';
+import {
+ Tabs,
+ TabsItem,
+} from '..';
+
+// Types for story component will be improved when we have full TypeScript support
+type TabItemForTestProps = HTMLAttributes;
+
+export const TabItemForTest = ({
+ ...props
+}: TabItemForTestProps) => (
+
+ {
+ e.preventDefault();
+ }}
+ {...props}
+ />
+
+);
diff --git a/src/components/Tabs/__tests__/Tabs.spec.tsx b/src/components/Tabs/__tests__/Tabs.spec.tsx
new file mode 100644
index 000000000..d323aa186
--- /dev/null
+++ b/src/components/Tabs/__tests__/Tabs.spec.tsx
@@ -0,0 +1,87 @@
+import React from 'react';
+import {
+ expect,
+ test,
+} from '@playwright/experimental-ct-react';
+import {
+ getActualFocusedElementText,
+ propTests,
+} from '../../../../tests/playwright';
+import { TabsForTest } from './Tabs.story';
+
+test.describe('Tabs', () => {
+ test.describe('visual', () => {
+ [
+ ...propTests.defaultComponentPropTest,
+ ].forEach(({
+ name,
+ onBeforeTest,
+ onBeforeSnapshot,
+ props,
+ }) => {
+ test(name, async ({
+ mount,
+ page,
+ }) => {
+ if (onBeforeTest) {
+ await onBeforeTest(page);
+ }
+ const component = await mount(
+ ,
+ );
+ if (onBeforeSnapshot) {
+ await onBeforeSnapshot(page, component);
+ }
+
+ const screenshot = await component.screenshot();
+ expect(screenshot).toMatchSnapshot();
+ });
+ });
+ });
+
+ test.describe('non-visual', () => {
+ test('id', async ({ mount }) => {
+ const id = 'test-id';
+
+ const component = await mount(
+ ,
+ );
+
+ expect(component.locator(`nav[id=${id}]`)).toBeDefined();
+ await expect(component.getByRole('list')).toHaveAttribute('id', `${id}__list`);
+ });
+ });
+
+ test.describe('functionality', () => {
+ test('has correct tab focus order', async ({
+ mount,
+ page,
+ }) => {
+ await mount(
+ ,
+ );
+
+ await page.keyboard.press('Tab');
+ const label1 = await getActualFocusedElementText(page);
+ expect(label1).toBe('Tab1');
+
+ await page.keyboard.press('Tab');
+ const label2 = await getActualFocusedElementText(page);
+ expect(label2).toBe('Tab2');
+
+ await page.keyboard.press('Tab');
+ const label3 = await getActualFocusedElementText(page);
+ expect(label3).toBe('Tab3');
+
+ await page.keyboard.press('Shift+Tab');
+ const label4 = await getActualFocusedElementText(page);
+ expect(label4).toBe('Tab2');
+
+ await page.keyboard.press('Shift+Tab');
+ const label5 = await getActualFocusedElementText(page);
+ expect(label5).toBe('Tab1');
+ });
+ });
+});
diff --git a/src/components/Tabs/__tests__/Tabs.spec.tsx-snapshots/Tabs-visual-defaultComponentProps-object-1-chromium-linux.png b/src/components/Tabs/__tests__/Tabs.spec.tsx-snapshots/Tabs-visual-defaultComponentProps-object-1-chromium-linux.png
new file mode 100644
index 000000000..493d4a361
Binary files /dev/null and b/src/components/Tabs/__tests__/Tabs.spec.tsx-snapshots/Tabs-visual-defaultComponentProps-object-1-chromium-linux.png differ
diff --git a/src/components/Tabs/__tests__/Tabs.story.tsx b/src/components/Tabs/__tests__/Tabs.story.tsx
new file mode 100644
index 000000000..b31351764
--- /dev/null
+++ b/src/components/Tabs/__tests__/Tabs.story.tsx
@@ -0,0 +1,42 @@
+import React, { useState } from 'react';
+import type { HTMLAttributes } from 'react';
+import {
+ Tabs,
+ TabsItem,
+} from '..';
+
+// Types for story component will be improved when we have full TypeScript support
+type TabsForTestProps = HTMLAttributes;
+
+export const TabsForTest = ({
+ ...props
+}: TabsForTestProps) => {
+ const [activeTab, setActiveTab] = useState(1);
+ const navigate = (event: Event, tab: number) => {
+ setActiveTab(tab);
+ event.preventDefault();
+ };
+
+ return (
+
+ navigate(e, 1)}
+ />
+ navigate(e, 2)}
+ />
+ navigate(e, 3)}
+ />
+
+ );
+};
diff --git a/src/components/Tabs/__tests__/Tabs.test.jsx b/src/components/Tabs/__tests__/Tabs.test.jsx
deleted file mode 100644
index 07499d167..000000000
--- a/src/components/Tabs/__tests__/Tabs.test.jsx
+++ /dev/null
@@ -1,47 +0,0 @@
-import React from 'react';
-import {
- render,
- within,
-} from '@testing-library/react';
-import { Tabs } from '../Tabs';
-import { TabsItem } from '../TabsItem';
-
-const tab = (
-
-);
-
-const defaultProps = {
- children: 'sample text',
-};
-
-describe('rendering', () => {
- it.each([
- [
- { children: tab },
- (rootElement) => expect(within(rootElement).getByText('label')),
- ],
- [
- { children: [tab] },
- (rootElement) => expect(within(rootElement).getByText('label')),
- ],
- [
- { id: 'id' },
- (rootElement) => {
- expect(rootElement).toHaveAttribute('id', 'id');
- expect(within(rootElement).getByTestId('id__list'));
- },
- ],
- ])('renders with props: "%s"', (testedProps, assert) => {
- const dom = render((
-
- ));
-
- assert(dom.container.firstChild);
- });
-});
diff --git a/src/components/Tabs/__tests__/TabsItem.test.jsx b/src/components/Tabs/__tests__/TabsItem.test.jsx
deleted file mode 100644
index 6e0fadd2a..000000000
--- a/src/components/Tabs/__tests__/TabsItem.test.jsx
+++ /dev/null
@@ -1,75 +0,0 @@
-import React from 'react';
-import {
- render,
- screen,
- within,
-} from '@testing-library/react';
-import userEvent from '@testing-library/user-event';
-import { labelPropTest } from '../../../../tests/jest/propTests/labelPropTest';
-import { TabsItem } from '../TabsItem';
-
-const mandatoryProps = {
- href: 'href',
- label: 'label',
-};
-
-describe('rendering', () => {
- it.each([
- [
- { afterLabel: after label
},
- (rootElement) => expect(within(rootElement).getByText('after label')),
- ],
- [
- { beforeLabel: before label
},
- (rootElement) => expect(within(rootElement).getByText('before label')),
- ],
- [
- { href: 'href' },
- (rootElement) => expect(rootElement).toContainHTML('href="href"'),
- ],
- [
- { id: 'id' },
- (rootElement) => {
- expect(rootElement).toHaveAttribute('id', 'id');
- expect(within(rootElement).getByText('label')).toHaveAttribute('id', 'id__label');
- expect(within(rootElement).getByTestId('id__link')).toHaveAttribute('href', 'href');
- },
- ],
- [
- { isActive: true },
- (rootElement) => expect(rootElement).toHaveClass('isRootActive'),
- ],
- [
- { isActive: false },
- (rootElement) => expect(rootElement).not.toHaveClass('isRootActive'),
- ],
- ...labelPropTest(),
- ])('renders with props: "%s"', (testedProps, assert) => {
- const dom = render((
-
- ));
-
- assert(dom.container.firstChild);
- });
-});
-
-describe('functionality', () => {
- it('calls onClick() on navigating', async () => {
- const spy = jest.fn();
- render((
- {
- e.preventDefault(); // Prevent the default navigation behavior
- spy();
- }}
- />
- ));
-
- await userEvent.click(screen.getByText('label'));
- expect(spy).toHaveBeenCalled();
- });
-});
diff --git a/src/components/Tabs/__tests__/_propTests/tabItem/isActivePropTest.ts b/src/components/Tabs/__tests__/_propTests/tabItem/isActivePropTest.ts
new file mode 100644
index 000000000..241aaaa4a
--- /dev/null
+++ b/src/components/Tabs/__tests__/_propTests/tabItem/isActivePropTest.ts
@@ -0,0 +1,16 @@
+import type { PropTests } from '../../../../../../tests/playwright/types';
+
+export const isActivePropTest: PropTests = [
+ {
+ name: 'isActive:boolean=true',
+ props: {
+ isActive: true,
+ },
+ },
+ {
+ name: 'isActive:boolean=false',
+ props: {
+ isActive: false,
+ },
+ },
+];
diff --git a/src/components/Text/__tests__/Text.spec.tsx b/src/components/Text/__tests__/Text.spec.tsx
new file mode 100644
index 000000000..ea85a151a
--- /dev/null
+++ b/src/components/Text/__tests__/Text.spec.tsx
@@ -0,0 +1,84 @@
+import React from 'react';
+import {
+ expect,
+ test,
+} from '@playwright/experimental-ct-react';
+import { propTests } from '../../../../tests/playwright';
+import {
+ TextForRenderTest,
+ TextForTest,
+} from './Text.story';
+import { linesPropTest } from './_propTests/linesPropTest';
+import { wordWrappingPropTest } from './_propTests/wordWrappingPropTest';
+import { hyphensPropTest } from './_propTests/hiphensPropTest';
+
+test.describe('Text', () => {
+ test.describe('visual', () => {
+ [
+ ...propTests.defaultComponentPropTest,
+ ...hyphensPropTest,
+ ...linesPropTest,
+ ...wordWrappingPropTest,
+ ].forEach(({
+ name,
+ onBeforeTest,
+ onBeforeSnapshot,
+ props,
+ }) => {
+ test(name, async ({
+ mount,
+ page,
+ }) => {
+ if (onBeforeTest) {
+ await onBeforeTest(page);
+ }
+ const component = await mount(
+ ,
+ );
+ if (onBeforeSnapshot) {
+ await onBeforeSnapshot(page, component);
+ }
+ const screenshot = await component.screenshot();
+ expect(screenshot).toMatchSnapshot();
+ });
+ });
+ });
+
+ test.describe('non-visual', () => {
+ test('id', async ({ mount }) => {
+ const id = 'test-id';
+ const children = 'Test';
+
+ const component = await mount(
+
+ {children}
+ ,
+ );
+
+ await expect(component.getByText(children)).toHaveAttribute('id', id);
+ });
+
+ test('render div when blockLevel is true', async ({ mount }) => {
+ const component = await mount(
+ ,
+ );
+
+ expect(component.locator('div')).toBeDefined();
+ });
+ });
+
+ test.describe('functionality', () => {
+ test('should render null when no children', async ({ mount }) => {
+ const component = await mount(
+
+ {null}
+ ,
+ );
+
+ const innerHTML = await component.innerHTML();
+ expect(innerHTML).toBe('');
+ });
+ });
+});
diff --git a/src/components/Text/__tests__/Text.spec.tsx-snapshots/Text-visual-defaultComponentProps-object-1-chromium-linux.png b/src/components/Text/__tests__/Text.spec.tsx-snapshots/Text-visual-defaultComponentProps-object-1-chromium-linux.png
new file mode 100644
index 000000000..1c9881ba6
Binary files /dev/null and b/src/components/Text/__tests__/Text.spec.tsx-snapshots/Text-visual-defaultComponentProps-object-1-chromium-linux.png differ
diff --git a/src/components/Text/__tests__/Text.spec.tsx-snapshots/Text-visual-hyphens-string-auto-1-chromium-linux.png b/src/components/Text/__tests__/Text.spec.tsx-snapshots/Text-visual-hyphens-string-auto-1-chromium-linux.png
new file mode 100644
index 000000000..9120442ea
Binary files /dev/null and b/src/components/Text/__tests__/Text.spec.tsx-snapshots/Text-visual-hyphens-string-auto-1-chromium-linux.png differ
diff --git a/src/components/Text/__tests__/Text.spec.tsx-snapshots/Text-visual-hyphens-string-manual-1-chromium-linux.png b/src/components/Text/__tests__/Text.spec.tsx-snapshots/Text-visual-hyphens-string-manual-1-chromium-linux.png
new file mode 100644
index 000000000..81281f951
Binary files /dev/null and b/src/components/Text/__tests__/Text.spec.tsx-snapshots/Text-visual-hyphens-string-manual-1-chromium-linux.png differ
diff --git a/src/components/Text/__tests__/Text.spec.tsx-snapshots/Text-visual-hyphens-string-none-1-chromium-linux.png b/src/components/Text/__tests__/Text.spec.tsx-snapshots/Text-visual-hyphens-string-none-1-chromium-linux.png
new file mode 100644
index 000000000..81281f951
Binary files /dev/null and b/src/components/Text/__tests__/Text.spec.tsx-snapshots/Text-visual-hyphens-string-none-1-chromium-linux.png differ
diff --git a/src/components/Text/__tests__/Text.spec.tsx-snapshots/Text-visual-lines-number-1-1-chromium-linux.png b/src/components/Text/__tests__/Text.spec.tsx-snapshots/Text-visual-lines-number-1-1-chromium-linux.png
new file mode 100644
index 000000000..1c9881ba6
Binary files /dev/null and b/src/components/Text/__tests__/Text.spec.tsx-snapshots/Text-visual-lines-number-1-1-chromium-linux.png differ
diff --git a/src/components/Text/__tests__/Text.spec.tsx-snapshots/Text-visual-lines-number-3-1-chromium-linux.png b/src/components/Text/__tests__/Text.spec.tsx-snapshots/Text-visual-lines-number-3-1-chromium-linux.png
new file mode 100644
index 000000000..1c9881ba6
Binary files /dev/null and b/src/components/Text/__tests__/Text.spec.tsx-snapshots/Text-visual-lines-number-3-1-chromium-linux.png differ
diff --git a/src/components/Text/__tests__/Text.spec.tsx-snapshots/Text-visual-lines-number-5-1-chromium-linux.png b/src/components/Text/__tests__/Text.spec.tsx-snapshots/Text-visual-lines-number-5-1-chromium-linux.png
new file mode 100644
index 000000000..1c9881ba6
Binary files /dev/null and b/src/components/Text/__tests__/Text.spec.tsx-snapshots/Text-visual-lines-number-5-1-chromium-linux.png differ
diff --git a/src/components/Text/__tests__/Text.spec.tsx-snapshots/Text-visual-wordWrapping-string-anywhere-1-chromium-linux.png b/src/components/Text/__tests__/Text.spec.tsx-snapshots/Text-visual-wordWrapping-string-anywhere-1-chromium-linux.png
new file mode 100644
index 000000000..c55f52d17
Binary files /dev/null and b/src/components/Text/__tests__/Text.spec.tsx-snapshots/Text-visual-wordWrapping-string-anywhere-1-chromium-linux.png differ
diff --git a/src/components/Text/__tests__/Text.spec.tsx-snapshots/Text-visual-wordWrapping-string-long-words-1-chromium-linux.png b/src/components/Text/__tests__/Text.spec.tsx-snapshots/Text-visual-wordWrapping-string-long-words-1-chromium-linux.png
new file mode 100644
index 000000000..3949ca640
Binary files /dev/null and b/src/components/Text/__tests__/Text.spec.tsx-snapshots/Text-visual-wordWrapping-string-long-words-1-chromium-linux.png differ
diff --git a/src/components/Text/__tests__/Text.spec.tsx-snapshots/Text-visual-wordWrapping-string-normal-1-chromium-linux.png b/src/components/Text/__tests__/Text.spec.tsx-snapshots/Text-visual-wordWrapping-string-normal-1-chromium-linux.png
new file mode 100644
index 000000000..9120442ea
Binary files /dev/null and b/src/components/Text/__tests__/Text.spec.tsx-snapshots/Text-visual-wordWrapping-string-normal-1-chromium-linux.png differ
diff --git a/src/components/Text/__tests__/Text.story.tsx b/src/components/Text/__tests__/Text.story.tsx
new file mode 100644
index 000000000..fc1aa70e0
--- /dev/null
+++ b/src/components/Text/__tests__/Text.story.tsx
@@ -0,0 +1,35 @@
+import React from 'react';
+import type { HTMLAttributes } from 'react';
+import { Text } from '..';
+
+// Types for story component will be improved when we have full TypeScript support
+type TextForTestProps = HTMLAttributes;
+type TextForRenderTestProps = { children: React.ReactNode };
+
+export const TextForTest = ({
+ ...props
+}: TextForTestProps) => {
+ const {
+ children,
+ ...restProps
+ } = props;
+
+ return (
+
+
+ { children || 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo.'}
+
+
+ );
+};
+
+export const TextForRenderTest = ({ children }: TextForRenderTestProps) => (
+
+ {children}
+
+);
diff --git a/src/components/Text/__tests__/Text.test.jsx b/src/components/Text/__tests__/Text.test.jsx
deleted file mode 100644
index 3afff1eaa..000000000
--- a/src/components/Text/__tests__/Text.test.jsx
+++ /dev/null
@@ -1,82 +0,0 @@
-import React from 'react';
-import {
- render,
- within,
-} from '@testing-library/react';
-import { Text } from '../Text';
-
-const defaultProps = {
- children: 'sample text',
-};
-
-describe('rendering', () => {
- it.each([
- [
- { blockLevel: true },
- (rootElement) => expect(rootElement).toContainHTML('sample text
'),
- ],
- [
- { blockLevel: false },
- (rootElement) => expect(rootElement).toContainHTML('sample text '),
- ],
- [
- { children: 'content text' },
- (rootElement) => expect(within(rootElement).getByText('content text')),
- ],
- [
- { children: undefined },
- (rootElement) => expect(rootElement).not.toBeInTheDocument(),
- ],
- [
- { hyphens: 'none' },
- (rootElement) => {
- expect(rootElement).not.toHaveClass('isRootHyphensAuto');
- expect(rootElement).not.toHaveClass('isRootHyphensManual');
- },
- ],
- [
- { hyphens: 'auto' },
- (rootElement) => expect(rootElement).toHaveClass('isRootHyphensAuto'),
- ],
- [
- { hyphens: 'manual' },
- (rootElement) => expect(rootElement).toHaveClass('isRootHyphensManual'),
- ],
- [
- { lines: 0 },
- (rootElement) => expect(rootElement).not.toHaveClass('isRootClampLines'),
- ],
- [
- { lines: 1 },
- (rootElement) => expect(rootElement).toHaveClass('isRootClampSingleLine'),
- ],
- [
- { lines: 2 },
- (rootElement) => expect(rootElement).toHaveClass('isRootClampMultiLine'),
- ],
- [
- { wordWrapping: 'normal' },
- (rootElement) => {
- expect(rootElement).not.toHaveClass('isRootWordWrappingAnywhere');
- expect(rootElement).not.toHaveClass('isRootWordWrappingLongWords');
- },
- ],
- [
- { wordWrapping: 'long-words' },
- (rootElement) => expect(rootElement).toHaveClass('isRootWordWrappingLongWords'),
- ],
- [
- { wordWrapping: 'anywhere' },
- (rootElement) => expect(rootElement).toHaveClass('isRootWordWrappingAnywhere'),
- ],
- ])('renders with props: "%s"', (testedProps, assert) => {
- const dom = render((
-
- ));
-
- assert(dom.container.firstChild);
- });
-});
diff --git a/src/components/Text/__tests__/_propTests/hiphensPropTest.tsx b/src/components/Text/__tests__/_propTests/hiphensPropTest.tsx
new file mode 100644
index 000000000..1a8fc2356
--- /dev/null
+++ b/src/components/Text/__tests__/_propTests/hiphensPropTest.tsx
@@ -0,0 +1,44 @@
+import React from 'react';
+import type { PropTests } from '../../../../../tests/playwright/types';
+
+export const hyphensPropTest: PropTests = [
+ {
+ name: 'hyphens:string=none',
+ props: {
+ children: (
+ <>
+ LongWordThatHasManualBreakingPossibilities
+ and a couple of ordinary words that are nice and well behaved.
+ >
+ ),
+ hyphens: 'none',
+ wordWrapping: 'normal',
+ },
+ },
+ {
+ name: 'hyphens:string=auto',
+ props: {
+ children: (
+ <>
+ LongWordThatHasNoBreakingPossibilities
+ and a couple of ordinary words that are nice and well behaved.
+ >
+ ),
+ hyphens: 'auto',
+ wordWrapping: 'normal',
+ },
+ },
+ {
+ name: 'hyphens:string=manual',
+ props: {
+ children: (
+ <>
+ LongWordThatHasManualBreakingPossibilities
+ and a couple of ordinary words that are nice and well behaved.
+ >
+ ),
+ hyphens: 'manual',
+ wordWrapping: 'normal',
+ },
+ },
+];
diff --git a/src/components/Text/__tests__/_propTests/linesPropTest.ts b/src/components/Text/__tests__/_propTests/linesPropTest.ts
new file mode 100644
index 000000000..36850a9ec
--- /dev/null
+++ b/src/components/Text/__tests__/_propTests/linesPropTest.ts
@@ -0,0 +1,10 @@
+import type { PropTests } from '../../../../../tests/playwright/types';
+
+const lines = [1, 3, 5];
+
+export const linesPropTest: PropTests = lines.map((line) => ({
+ name: `lines:number=${line}`,
+ props: {
+ lines,
+ },
+}));
diff --git a/src/components/Text/__tests__/_propTests/wordWrappingPropTest.tsx b/src/components/Text/__tests__/_propTests/wordWrappingPropTest.tsx
new file mode 100644
index 000000000..c414d57ac
--- /dev/null
+++ b/src/components/Text/__tests__/_propTests/wordWrappingPropTest.tsx
@@ -0,0 +1,41 @@
+import React from 'react';
+import type { PropTests } from '../../../../../tests/playwright/types';
+
+export const wordWrappingPropTest: PropTests = [
+ {
+ name: 'wordWrapping:string=normal',
+ props: {
+ children: (
+ <>
+ LongWordThatHasNoBreakingPossibilities
+ and a couple of ordinary words that are nice and well behaved.
+ >
+ ),
+ wordWrapping: 'normal',
+ },
+ },
+ {
+ name: 'wordWrapping:string=long-words',
+ props: {
+ children: (
+ <>
+ LongWordThatHasNoBreakingPossibilities
+ and a couple of ordinary words that are nice and well behaved.
+ >
+ ),
+ wordWrapping: 'long-words',
+ },
+ },
+ {
+ name: 'wordWrapping:string=anywhere',
+ props: {
+ children: (
+ <>
+ LongWordThatHasNoBreakingPossibilities
+ and a couple of ordinary words that are nice and well behaved.
+ >
+ ),
+ wordWrapping: 'anywhere',
+ },
+ },
+];
diff --git a/tests/playwright/index.ts b/tests/playwright/index.ts
index 86173244d..3fb70ff09 100644
--- a/tests/playwright/index.ts
+++ b/tests/playwright/index.ts
@@ -19,6 +19,7 @@ import { labelVisibilityPropTest } from './propTests/labelVisibilityPropTest';
import { layoutPropTest } from './propTests/layoutPropTest';
import { neutralColorPropTest } from './propTests/neutralColorPropTest';
import { priorityPropTest } from './propTests/priorityPropTest';
+import { raisedPropTest } from './propTests/raisedPropTest';
import { renderAsRequiredPropTest } from './propTests/renderAsRequiredPropTest';
import { sizePropTest } from './propTests/sizePropTest';
import { startCornerPropTest } from './propTests/startCornerPropTest';
@@ -30,6 +31,7 @@ import { requiredPropTest } from './propTests/requiredPropTest';
export { TestIcon } from './components/TestIcon';
export { mixPropTests } from './utils/mixPropTests';
+export { getActualFocusedElementText } from './utils/getActualFocusedElementText';
export const propTests = {
actionColorPropTest,
@@ -53,6 +55,7 @@ export const propTests = {
layoutPropTest,
neutralColorPropTest,
priorityPropTest,
+ raisedPropTest,
renderAsRequiredPropTest,
requiredPropTest,
sizePropTest,
diff --git a/tests/playwright/propTests/raisedPropTest.ts b/tests/playwright/propTests/raisedPropTest.ts
new file mode 100644
index 000000000..8a6dedb5b
--- /dev/null
+++ b/tests/playwright/propTests/raisedPropTest.ts
@@ -0,0 +1,12 @@
+import type { PropTests } from '../types';
+
+export const raisedPropTest: PropTests = [
+ {
+ name: 'raised:boolean=true',
+ props: { raised: true },
+ },
+ {
+ name: 'raised:boolean=false',
+ props: { raised: false },
+ },
+];
diff --git a/tests/playwright/utils/getActualFocusedElementText.ts b/tests/playwright/utils/getActualFocusedElementText.ts
new file mode 100644
index 000000000..826966454
--- /dev/null
+++ b/tests/playwright/utils/getActualFocusedElementText.ts
@@ -0,0 +1,6 @@
+import type { Page } from 'playwright/test';
+
+export const getActualFocusedElementText = (page: Page) => page.evaluate(() => {
+ const selector = document.activeElement;
+ return selector ? selector.textContent : null;
+});