Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8956 - Improve swaplist drop area #8978

Merged
merged 9 commits into from
Aug 27, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
- `[General]` Upgrade dependencies, this involved updating sass and test dependencies with a few css deprecations that were fixed. ([#8947](https://github.com/infor-design/enterprise-ng/issues/8947))
- `[Message]` Updated docs in settings. ([#8839](https://github.com/infor-design/enterprise/issues/8839))
- `[ModuleNav]` Fixed a bug where the tooltip was not showing when collapsed by default. ([NG#1678](https://github.com/infor-design/enterprise-ng/issues/1678))
- `[Swaplist]` Improved the size of the swaplist's drop area when there is no existing items. ([#8956](https://github.com/infor-design/enterprise/issues/8956))
- `[Toolbar]` Fixed uncaught error when destroying the toolbar. ([#8946](https://github.com/infor-design/enterprise/issues/8946))
- `[Tabs]` Fixed a bug where focus state is undefined when using breadcrumbs startup. ([#8910](https://github.com/infor-design/enterprise/issues/8910))

Expand Down
77 changes: 75 additions & 2 deletions docs/TESTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,79 @@ npm run test
For development purposes you may just want to run one test your focusing on.

```sh
npm run test
npm run test -- component_name
```

## Visual Testing with Percy and Playwright

This project demonstrates how to perform visual testing using Percy and Playwright. Visual testing helps ensure that UI changes do not introduce unexpected visual regressions. The provided example captures visual snapshots of different UI states to verify consistent rendering.

### Table of Contents

- [Introduction](#introduction)
- [Example Test](#example-test)
- [Usage](#usage)
- [Best Practices](#best-practices-for-visual-testing)

### Introduction

Visual testing is a crucial part of maintaining a consistent user interface. By comparing the appearance of web pages or components against known good baselines, visual testing tools like Percy can automatically detect unintended visual changes.

### Example Test

```javascript
test.describe('snapshot tests', () => {
test('should match the visual snapshot in percy', async ({ page, browserName }) => {
if (browserName !== 'chromium') return;

// Function to handle the actions and snapshot for specific row option
const captureSnapshot = async (option, snapshotName) => {
await page.locator('#custom-id-actions').click();
await page.locator(`a[data-option="row-${option}"]`).click();

// Capture a Percy snapshot with the specified name
await percySnapshot(page, snapshotName);
};

// Capture snapshot for "extra-small" row height
await captureSnapshot('extra-small', 'datagrid-expandable-row-extra-small-padding');

// Capture snapshot for "small" row height
await captureSnapshot('small', 'datagrid-expandable-row-small-padding');

// Capture snapshot for "medium" row height
await captureSnapshot('medium', 'datagrid-expandable-row-medium-padding');

// Capture snapshot for "large" / "Normal" row height
await captureSnapshot('large', 'datagrid-expandable-row-large-padding');
});
});
```

### Usage

To run the visual tests locally, you can use the following command:

Run all visual tests:

```sh
PERCY_TOKEN=your-percy-token npm run test:visual
```

## Visual Regression testing
Run specific tests:

```sh
PERCY_TOKEN=your-percy-token npm run test:visual -- component_name
```

For the visual tests to work, you need to set the `PERCY_TOKEN` environment variable to your Percy token. You can find your Percy token in your Percy project settings.

### Best Practices for Visual Testing

- Run Visual Tests in a Stable Environment: Ensure that tests are run in a consistent and stable environment to avoid flaky results.
- Test Across Browsers: Consider capturing snapshots in multiple browsers to catch cross-browser inconsistencies.
- Review Snapshots Regularly: Regularly review and approve or reject snapshot changes to keep the baseline up-to-date.
- Use Percy's Review Workflow: Use Percy's review workflow to collaborate with your team and ensure that visual changes are intentional.

## Debugging Functional Tests

Expand All @@ -74,6 +143,10 @@ Each component should have a passing test with Axe. This tool will verify a few

If your having an issue with one of these tests you can either debug and follow the above steps for debugging a test or you can install the [Axe Chrome Dev Tools Plugin](https://chrome.google.com/webstore/detail/axe/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US). This tool should give you the same output as the test when you run the page on port 4000 instead of 3000 as the tests do.

## Contributing

Contributions are welcome! If you have suggestions or improvements, please submit a pull request.

## Reusing Tests Across Repos

Listing some common differences in reusing the tests.
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
"test:start-server": "node app/server.js --test-port",
"test": "PERCY_LOGLEVEL=silent npx playwright test --reporter=list",
"test:build": "npm run build:demoapp && npm run build",
"test:visual": "PERCY_LOGLEVEL=silent npx percy exec -- npx playwright test --reporter=list",
"test:coverage": "npx rimraf .nyc_output && npm run build:coverage && npm run test && npx nyc report && open coverage/index.html",
"test:coverage:no-build": "npx rimraf .nyc_output && npm run test && npx nyc report && open coverage/index.html",
"test:ci": "PERCY_LOGLEVEL=silent npx rimraf .nyc_output && npm run build:coverage && npm run test && npx nyc report",
Expand Down
2 changes: 1 addition & 1 deletion src/components/swaplist/_swaplist-new.scss
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

.card-content .listview,
.widget-content .listview {
li:first-child {
li:first-child:not(.over) {
border-top-color: transparent;
}
}
Expand Down
18 changes: 16 additions & 2 deletions src/components/swaplist/_swaplist.scss
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,19 @@

.card-content {
width: 100%;

.listview {
li {
border-radius: 0;

&:last-child {
&.over {
border: 1px dashed $swaplist-border-color !important;
border-bottom-color: inherit;
}
}
}
}
}

.card-header {
Expand Down Expand Up @@ -246,7 +259,7 @@
border-top: thin solid $swaplist-border-color-card;

ul {
min-height: 100%;
min-height: 40px;
padding: 0 0 5px;

&.is-not-droppable {
Expand Down Expand Up @@ -326,7 +339,8 @@
}

.over {
border: 1px dashed $swaplist-border-color;
border: 1px dashed $swaplist-border-color !important;
min-height: 40px;
}
}

Expand Down
58 changes: 38 additions & 20 deletions src/components/swaplist/swaplist.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,10 @@ SwapList.prototype = {

init() {
const s = this.settings;
const additionalClass = `${s.additionalClass} .listview`;
s.draggable = $.extend(true, SWAPLIST_DEFAULTS.draggable, s.draggable);
this.isTouch = env.features.touch;
this.isAdditional = $(`${s.additionalClass} .listview`, this.element).length > 0;
this.isAdditional = $(additionalClass, this.element).length > 0;

if (this.isTouch) {
this.element.addClass('is-touch');
Expand Down Expand Up @@ -136,10 +137,12 @@ SwapList.prototype = {

for (let i = 0, l = containers.length; i < l; i++) {
const c = containers[i];
const lv = $(`${c.class} .listview`, this.element);
const listviewContainerClass = `${c.class} .listview`;
const lv = $(listviewContainerClass, this.element);
const list = lv.data('listview');
const searchfieldContainerClass = `${c.class} .searchfield`;
const options = { dataset: c.dataset || [], selectable: 'multiple', showCheckboxes: false };
const isSearchable = ((s.searchable === true || s.searchable === 'true') && ($(`${c.class} .searchfield`, this.element).length > 0));
const isSearchable = ((s.searchable === true || s.searchable === 'true') && ($(searchfieldContainerClass, this.element).length > 0));

if (isSearchable) {
options.searchable = true;
Expand Down Expand Up @@ -219,17 +222,23 @@ SwapList.prototype = {

this.offset = null;

this.containers = $(`${s.availableClass},${
s.selectedClass},${
s.additionalClass}`, this.element);
const { availableClass, selectedClass, additionalClass } = s;
const { availableBtn, additionalBtn, selectedBtnLeft, selectedBtnRight } = s;

this.actionButtons = $(`${s.availableBtn},${
s.additionalBtn},${
s.selectedBtnLeft},${
s.selectedBtnRight}`, this.element);
this.containers = $(
`${availableClass}, ${selectedClass}, ${additionalClass}`,
this.element
);

this.selectedButtons = $(`${s.selectedBtnLeft},${
s.selectedBtnRight}`, this.element);
this.actionButtons = $(
`${availableBtn},${additionalBtn},${selectedBtnLeft},${selectedBtnRight}`,
this.element
);

this.selectedButtons = $(
`${selectedBtnLeft},${selectedBtnRight}`,
this.element
);

this.tabButtonsStr = `${
s.availableBtn}, ${
Expand Down Expand Up @@ -672,7 +681,8 @@ SwapList.prototype = {

for (let i = 0, l = containers.length; i < l; i++) {
const c = containers[i];
const nodes = $(`${c.class} .listview li`, this.element);
const classSelector = `${c.class} .listview li`;
const nodes = $(classSelector, this.element);

for (let nodeIndex = 0, l2 = nodes.length; nodeIndex < l2; nodeIndex++) {
let data;
Expand Down Expand Up @@ -961,7 +971,8 @@ SwapList.prototype = {

for (let i = 0, l = containers.length; i < l; i++) {
const c = containers[i];
const lv = $(`${c.class} .listview`, this.element);
const classSelector = `${c.class} .listview`;
const lv = $(classSelector, this.element);
const api = lv.data('listview');

if (api) {
Expand Down Expand Up @@ -1187,16 +1198,20 @@ SwapList.prototype = {
return;
}

$(`.${settings.numOfSelectionsClass}`, settings.itemContentTempl).html(selections.items.length);
$(`.${settings.numOfSelectionsClass}-text`, settings.itemContentTempl).text(Locale.translate('ItemsSelected'));
const selectionClass = `.${settings.numOfSelectionsClass}`;
const selectionClassText = `${selectionClass}-text`;

$(selectionClass, settings.itemContentTempl).html(selections.items.length);
$(selectionClassText, settings.itemContentTempl).text(Locale.translate('ItemsSelected'));
self.addDropeffects();

if (!self.isTouch) {
selections.dragged.addClass('is-dragging');
e.originalEvent.dataTransfer.setData('text', '');

if (selections.items.length > 1) {
$(`.${settings.itemContentClass}`, selections.dragged).html(settings.itemContentTempl.html());
const itemContentClass = `.${settings.itemContentClass}`;
$(itemContentClass, selections.dragged).html(settings.itemContentTempl.html());
}
} else {
rect = target[0].getBoundingClientRect();
Expand Down Expand Up @@ -1265,7 +1280,8 @@ SwapList.prototype = {
if (!selections.isInSelection) {
self.draggedMakeSelected(list, selections.dragged);
selections.items = list.selectedItems;
$(`.${settings.numOfSelectionsClass}`, settings.itemContentTempl).html(selections.items.length);
const selectionClass = `.${settings.numOfSelectionsClass}`;
$(selectionClass, settings.itemContentTempl).html(selections.items.length);
}

touch = e.originalEvent.touches[0];
Expand All @@ -1282,7 +1298,8 @@ SwapList.prototype = {
.slideUp();

if (selections.items.length > 1) {
$(`.${settings.itemContentClass}`, (selections.placeholderTouch.add('#sl-placeholder-touch2')))
const itemContentClass = `.${settings.itemContentClass}`;
$(itemContentClass, (selections.placeholderTouch.add('#sl-placeholder-touch2')))
.html(settings.itemContentTempl.html());

$('#sl-placeholder-touch2').show();
Expand Down Expand Up @@ -1331,7 +1348,8 @@ SwapList.prototype = {
});

if (selections.items.length > 1) {
$(`.${settings.itemContentClass}`, selections.dragged).html($(`.${settings.itemContentClass}`, selections.placeholder).html());
const itemContentClass = `.${settings.itemContentClass}`;
$(itemContentClass, selections.dragged).html($(itemContentClass, selections.placeholder).html());
if (self.isTouch) {
selections.dragged.show();
}
Expand Down
Loading