Added data-cy for table widget elements (#4792)

* Add data-cy to tooltip label

* Add data-cy to table filter pop-over

* Add data-cy to table elements

* Add review changes
This commit is contained in:
Midhun Kumar E 2022-11-18 09:16:19 +05:30 committed by GitHub
parent 8824c00896
commit 1b270ab412
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 85 additions and 23 deletions

View file

@ -113,10 +113,12 @@ export function Filter(props) {
<div className="table-filters card">
<div className="card-header row">
<div className="col">
<h4 className="font-weight-normal">Filters</h4>
<h4 data-cy={`header-filters`} className="font-weight-normal">
Filters
</h4>
</div>
<div className="col-auto">
<button onClick={() => props.hideFilters()} className="btn btn-light btn-sm">
<button data-cy={`button-close-filters`} onClick={() => props.hideFilters()} className="btn btn-light btn-sm">
x
</button>
</div>
@ -131,9 +133,9 @@ export function Filter(props) {
{props.filters.map((filter, index) => (
<div className="row mb-2" key={index}>
<div className="col p-2" style={{ maxWidth: '70px' }}>
<small>{index > 0 ? 'and' : 'column'}</small>
<small data-cy={`label-filter-column`}>{index > 0 ? 'and' : 'column'}</small>
</div>
<div className="col">
<div data-cy={`select-coloumn-dropdown-${index ?? ''}`} className="col">
<Select
options={props.columns}
value={filter.id}
@ -144,7 +146,7 @@ export function Filter(props) {
styles={selectStyles('100%')}
/>
</div>
<div className="col" style={{ maxWidth: '180px' }}>
<div data-cy={`select-operation-dropdown-${index ?? ''}`} className="col" style={{ maxWidth: '180px' }}>
<Select
options={[
{ name: 'contains', value: 'contains' },
@ -168,11 +170,13 @@ export function Filter(props) {
className={`${darkMode ? 'select-search-dark' : 'select-search'}`}
placeholder={t('globals.select', 'Select') + '...'}
styles={selectStyles('100%')}
dataCy={`select-coloumn-dropdown-${index ?? ''}`}
/>
</div>
<div className="col">
{['isEmpty', 'isNotEmpty'].includes(filter.value.condition) || (
<input
data-cy={`data-filtervalue-input-${index ?? ''}`}
type="text"
value={filter.value.value}
placeholder="value"
@ -183,6 +187,7 @@ export function Filter(props) {
</div>
<div className="col-auto">
<button
data-cy={`button-close-filter-${index ?? ''}`}
onClick={() => removeFilter(index)}
className={`btn ${darkMode ? 'btn-dark' : 'btn-light'} btn-sm p-2 text-danger font-weight-bold`}
>
@ -194,16 +199,16 @@ export function Filter(props) {
{props.filters.length === 0 && (
<div>
<center>
<span>no filters yet.</span>
<span data-cy={`label-no-filters`}>no filters yet.</span>
</center>
</div>
)}
</div>
<div className="card-footer">
<button onClick={addFilter} className="btn btn-light btn-sm">
<button data-cy={`button-add-filter`} onClick={addFilter} className="btn btn-light btn-sm">
+ add filter
</button>
<button onClick={() => clearFilters()} className="btn btn-light btn-sm mx-2">
<button data-cy={`button-clear-filters`} onClick={() => clearFilters()} className="btn btn-light btn-sm mx-2">
clear filters
</button>
</div>

View file

@ -31,6 +31,7 @@ export const GlobalFilter = ({
defaultValue={value || ''}
onChange={(e) => onChange(e.target.value)}
placeholder="Search"
data-cy="search-input-field"
style={{
border: '0',
}}

View file

@ -11,6 +11,7 @@ const IndeterminateCheckbox = React.forwardRef(({ indeterminate, ...rest }, ref)
return (
<>
<input
data-cy={`checkbox-input`}
type="checkbox"
ref={resolvedRef}
style={{

View file

@ -50,6 +50,7 @@ export const Pagination = function Pagination({
<div className="pagination justify-content-start">
{!serverSide && (
<button
data-cy={`pagination-button-to-first`}
className={`btn btn-sm btn-light mx-2 ${pageIndex === 1 ? 'cursor-not-allowed' : ''}`}
onClick={() => gotoPage(1)}
disabled={pageIndex === 1}
@ -58,13 +59,14 @@ export const Pagination = function Pagination({
</button>
)}
<button
data-cy={`pagination-button-to-previous`}
className={`btn btn-sm btn-light ${pageIndex === 1 ? 'cursor-not-allowed' : ''}`}
onClick={() => goToPreviousPage()}
disabled={pageIndex === 1 || !enablePrevButton}
>
{'<'}
</button>{' '}
<small className="p-1 mx-2">
<small className="p-1 mx-2" data-cy={`page-index-details`}>
{serverSide && <strong>{pageIndex}</strong>}
{!serverSide && (
<strong>
@ -73,6 +75,7 @@ export const Pagination = function Pagination({
)}
</small>
<button
data-cy={`pagination-button-to-next`}
className={`btn btn-light btn-sm ${!autoCanNextPage && !serverSide ? 'cursor-not-allowed' : ''}`}
onClick={() => goToNextPage()}
disabled={(!autoCanNextPage && !serverSide) || !enableNextButton}
@ -81,6 +84,7 @@ export const Pagination = function Pagination({
</button>{' '}
{!serverSide && (
<button
data-cy={`pagination-button-to-last`}
className={`btn btn-light btn-sm mx-2 ${!autoCanNextPage && !serverSide ? 'cursor-not-allowed' : ''}`}
onClick={() => gotoPage(pageCount)}
disabled={!autoCanNextPage && !serverSide}

View file

@ -533,10 +533,14 @@ export function Table({
>
<Popover.Content>
<div className="d-flex flex-column">
<span className="cursor-pointer" onClick={() => exportData('csv', true)}>
<span data-cy={`option-download-CSV`} className="cursor-pointer" onClick={() => exportData('csv', true)}>
Download as CSV
</span>
<span className="pt-2 cursor-pointer" onClick={() => exportData('xlsx', true)}>
<span
data-cy={`option-download-execel`}
className="pt-2 cursor-pointer"
onClick={() => exportData('xlsx', true)}
>
Download as Excel
</span>
</div>
@ -602,20 +606,32 @@ export function Table({
overlay={
<Popover>
<div
data-cy={`dropdown-hide-column`}
className={`dropdown-table-column-hide-common ${
darkMode ? 'dropdown-table-column-hide-dark-themed' : 'dropdown-table-column-hide'
} `}
>
<div className="dropdown-item">
<IndeterminateCheckbox {...getToggleHideAllColumnsProps()} />
<span className="hide-column-name"> Select All</span>
<span className="hide-column-name" data-cy={`options-select-all-coloumn`}>
Select All
</span>
</div>
{allColumns.map((column) => (
<div key={column.id}>
<div>
<label className="dropdown-item">
<input type="checkbox" {...column.getToggleHiddenProps()} />
<span className="hide-column-name"> {` ${column.Header}`}</span>
<input
type="checkbox"
data-cy={`checkbox-coloumn-${String(column.Header).toLowerCase().replace(/\s+/g, '-')}`}
{...column.getToggleHiddenProps()}
/>
<span
className="hide-column-name"
data-cy={`options-coloumn-${String(column.Header).toLowerCase().replace(/\s+/g, '-')}`}
>
{` ${column.Header}`}
</span>
</label>
</div>
</div>
@ -625,7 +641,7 @@ export function Table({
}
placement={'bottom-end'}
>
<span className={`btn btn-light btn-sm p-1 mb-0 mx-1 `}>
<span data-cy={`select-column-icon`} className={`btn btn-light btn-sm p-1 mb-0 mx-1 `}>
<IconEyeOff style={{ width: '15', height: '15', margin: '0px' }} />
</span>
</OverlayTrigger>
@ -685,6 +701,9 @@ export function Table({
}
>
<div
data-cy={`column-header-${String(column.exportValue)
.toLowerCase()
.replace(/\s+/g, '-')}`}
{...column.getSortByToggleProps()}
{...provided.draggableProps}
{...provided.dragHandleProps}
@ -782,6 +801,9 @@ export function Table({
// Does not require key as its already being passed by react-table via cellProps
// eslint-disable-next-line react/jsx-key
<td
data-cy={`${cell.column.columnType ?? ''}${String(
cell.column.id === 'rightActions' || cell.column.id === 'leftActions' ? cell.column.id : ''
)}${String(cellValue ?? '').toLocaleLowerCase()}-cell-${index}`}
className={cx(`${wrapAction ? wrapAction : 'wrap'}-wrapper`, {
'has-actions': cell.column.id === 'rightActions' || cell.column.id === 'leftActions',
'has-text': cell.column.columnType === 'text' || cell.column.isEditable,
@ -846,15 +868,20 @@ export function Table({
handleChangesSaved();
})
}
data-cy={`table-button-save-changes`}
>
Save Changes
</button>
<button className="btn btn-light btn-sm" onClick={() => handleChangesDiscarded()}>
<button
className="btn btn-light btn-sm"
onClick={() => handleChangesDiscarded()}
data-cy={`table-button-discard-changes`}
>
Discard changes
</button>
</>
) : (
<span>
<span data-cy={`footer-number-of-records`}>
{clientSidePagination && !serverSidePagination && `${globalFilteredRows.length} Records`}
{serverSidePagination && totalRecords ? `${totalRecords} Records` : ''}
</span>

View file

@ -666,8 +666,11 @@ class TableComponent extends React.Component {
<Popover id="popover-basic" className={`${this.props.darkMode && 'popover-dark-themed theme-dark'} shadow`}>
<Popover.Content>
<div className="field mb-2">
<label className="form-label">{this.props.t('widget.Table.buttonText', 'Button Text')}</label>
<label data-cy={`label-action-button-text`} className="form-label">
{this.props.t('widget.Table.buttonText', 'Button Text')}
</label>
<input
data-cy={`action-button-text-input-field`}
type="text"
className="form-control text-field"
onChange={(e) => {
@ -677,8 +680,10 @@ class TableComponent extends React.Component {
value={action.buttonText}
/>
</div>
<div className="field mb-2">
<label className="form-label">{this.props.t('widget.Table.buttonPosition', 'Button Position')}</label>
<div className="field mb-2" data-cy={`dropdown-action-button-position`}>
<label data-cy={`label-action-button-position`} className="form-label">
{this.props.t('widget.Table.buttonPosition', 'Button Position')}
</label>
<SelectSearch
className={`${this.props.darkMode ? 'select-search-dark' : 'select-search'}`}
options={[
@ -701,6 +706,7 @@ class TableComponent extends React.Component {
componentMeta={this.state.componentMeta}
definition={{ value: action.backgroundColor }}
onChange={(name, value, color) => this.onActionButtonPropertyChanged(index, 'backgroundColor', color)}
cyLabel={`action-button-bg`}
/>
<Color
@ -709,6 +715,7 @@ class TableComponent extends React.Component {
componentMeta={this.state.componentMeta}
definition={{ value: action.textColor }}
onChange={(name, value, color) => this.onActionButtonPropertyChanged(index, 'textColor', color)}
cyLabel={`action-button-text`}
/>
<EventManager
component={dummyComponentForActionButton}
@ -743,7 +750,14 @@ class TableComponent extends React.Component {
<div className={`card p-2 mb-1 ${this.props.darkMode ? 'bg-secondary' : 'bg-light'}`} role="button">
<div className={`row ${this.props.darkMode ? '' : 'bg-light'}`}>
<div className="col-auto">
<div className="text">{action.buttonText}</div>
<div
data-cy={`action-button-${String(action.buttonText ?? '')
.toLowerCase()
.replace(/\s+/g, '-')}-${String(index ?? '')}`}
className="text"
>
{action.buttonText}
</div>
</div>
</div>
</div>
@ -959,6 +973,7 @@ class TableComponent extends React.Component {
<div className="row g-2">
<div className="text-right mb-3">
<button
data-cy="button-add-new-action-button"
onClick={this.addNewAction}
className="btn btn-sm border-0 font-weight-normal padding-2 col-auto color-primary inspector-add-button"
>
@ -969,7 +984,7 @@ class TableComponent extends React.Component {
<div>{actions.value.map((action, index) => this.actionButton(action, index))}</div>
{actions.value.length === 0 && (
<div className="text-center">
<small className="color-disabled">
<small data-cy="message-no-action-button" className="color-disabled">
{this.props.t('widget.Table.noActionMessage', "This table doesn't have any action buttons")}
</small>
</div>

View file

@ -25,6 +25,15 @@ export const ToolTip = ({ label, meta, labelClass }) => {
</OverlayTrigger>
);
} else {
return <label className={labelClass || 'form-label'}>{label}</label>;
return (
<label
data-cy={`label-${String(label ?? '')
.toLowerCase()
.replace(/\s+/g, '-')}`}
className={labelClass || 'form-label'}
>
{label}
</label>
);
}
};