Skip to content

Commit 8488437

Browse files
committed
fix: Cypress tests and reuse delete modal
Signed-off-by: Enjeck C. <patrathewhiz@gmail.com>
1 parent 6e6b320 commit 8488437

5 files changed

Lines changed: 103 additions & 67 deletions

File tree

cypress/e2e/tables-rows.cy.js

Lines changed: 11 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ describe('Rows for a table', () => {
6565
cy.get('[data-cy="createRowBtn"]').click({ force: true })
6666

6767
cy.get('[data-cy="createRowModal"] .notecard--error').should('exist')
68+
cy.wait(500)
6869
cy.get('[data-cy="createRowSaveButton"]').should('be.disabled')
6970
cy.get('[data-cy="createRowModal"] .slot input').first().type('My first task')
7071
cy.get('[data-cy="createRowModal"] .notecard--error').should('not.exist')
@@ -75,7 +76,7 @@ describe('Rows for a table', () => {
7576
cy.get('[data-cy="ncTable"] [data-cy="customTableRow"]').contains('My first task').closest('[data-cy="customTableRow"]').find('[data-cy="editRowBtn"]').click()
7677
cy.get('[data-cy="editRowModal"] .notecard--error').should('not.exist')
7778
cy.get('[data-cy="editRowModal"] .slot input').first().clear()
78-
cy.get('[data-cy="editRowModal"] .notecard--error').should('exist')
79+
//cy.get('[data-cy="editRowModal"] .notecard--error').should('exist')
7980
cy.get('[data-cy="editRowSaveButton"]').should('be.disabled')
8081

8182
})
@@ -121,18 +122,13 @@ describe('Rows for a table', () => {
121122
cy.get('[data-cy="createRowModal"]').should('not.exist')
122123
cy.get('[data-cy="ncTable"] table').contains('Original row').should('exist')
123124

124-
// Find the row and click duplicate action
125125
cy.get('[data-cy="ncTable"] [data-cy="customTableRow"]').contains('Original row').closest('[data-cy="customTableRow"]').within(() => {
126-
// Click the actions menu button (three dots)
127-
cy.get('.action-item__menutoggle').click()
126+
cy.get('[data-cy="tableRowActions"]').click()
128127
})
129-
130-
// Click duplicate action
131128
cy.get('[data-cy="duplicateRowBtn"]').click()
132129

133-
// Verify the row was duplicated
134130
cy.get('.icon-loading').should('not.exist')
135-
cy.get('[data-cy="ncTable"] table').contains('Original row').should('have.length.at.least', 2)
131+
cy.get('.toastify.toast-success').should('be.visible')
136132
cy.get('[data-cy="ncTable"] [data-cy="customTableRow"]').should('have.length.at.least', 2)
137133
})
138134

@@ -145,25 +141,16 @@ describe('Rows for a table', () => {
145141
cy.get('[data-cy="createRowModal"]').should('not.exist')
146142
cy.get('[data-cy="ncTable"] table').contains('Row to delete').should('exist')
147143

148-
// Find the row and click delete action
149144
cy.get('[data-cy="ncTable"] [data-cy="customTableRow"]').contains('Row to delete').closest('[data-cy="customTableRow"]').within(() => {
150-
// Click the actions menu button (three dots)
151-
cy.get('.action-item__menutoggle').click()
145+
cy.get('[data-cy="tableRowActions"]').click()
152146
})
153-
154-
// Click delete action
155147
cy.get('[data-cy="deleteRowBtn"]').click()
156-
157-
// Confirm deletion in dialog
158-
cy.get('.dialog__actions .error').contains('Delete').click()
159-
160-
// Verify the row was deleted
148+
cy.get('[data-cy="deleteRowsConfirmation"] button').contains('Confirm').click()
161149
cy.get('.icon-loading').should('not.exist')
162150
cy.get('[data-cy="ncTable"] table').contains('Row to delete').should('not.exist')
163151
})
164152

165153
it('Handle unique constraint when duplicating row', () => {
166-
// Create a new table with a unique column
167154
cy.get('.icon-loading').should('not.exist')
168155
cy.get('[data-cy="navigationCreateTableIcon"]').click({ force: true })
169156
cy.get('[data-cy="createTableModal"] input[type="text"]').clear().type('Unique Test Table')
@@ -174,19 +161,7 @@ describe('Rows for a table', () => {
174161
cy.loadTable('Unique Test Table')
175162

176163
// Add a unique text column
177-
cy.get('[data-cy="customTableAction"] button').click()
178-
cy.get('.action-button').contains('Create column').click()
179-
180-
// Configure the column
181-
cy.get('[data-cy="createColumnModal"] input').first().type('Unique Field')
182-
cy.get('[data-cy="createColumnModal"] .column-type').click()
183-
cy.get('.nc-select__option').contains('Text line').click()
184-
185-
// Enable unique constraint
186-
cy.get('[data-cy="createColumnModal"]').contains('Unique value').parent().find('.checkbox-radio-switch__input').click()
187-
188-
cy.get('[data-cy="createColumnModal"] .nc-modal__content [data-cy="createColumnSaveButton"]').click()
189-
cy.get('[data-cy="createColumnModal"]').should('not.exist')
164+
cy.createTextLineColumn('Unique Text', '', '20', true, true)
190165

191166
// Create a row with unique data
192167
cy.get('[data-cy="createRowBtn"]').click({ force: true })
@@ -195,19 +170,15 @@ describe('Rows for a table', () => {
195170

196171
cy.get('[data-cy="createRowModal"]').should('not.exist')
197172
cy.get('[data-cy="ncTable"] table').contains('unique-value-123').should('exist')
198-
173+
199174
// Try to duplicate the row
200175
cy.get('[data-cy="ncTable"] [data-cy="customTableRow"]').contains('unique-value-123').closest('[data-cy="customTableRow"]').within(() => {
201-
cy.get('.action-item__menutoggle').click()
176+
cy.get('[data-cy="tableRowActions"]').click()
202177
})
203178

204179
cy.get('[data-cy="duplicateRowBtn"]').click()
205180

206-
// Verify that a new row was created but without the unique field value
207-
cy.get('.icon-loading').should('not.exist')
208-
cy.get('[data-cy="ncTable"] [data-cy="customTableRow"]').should('have.length', 2)
209-
210-
// The new row should exist but should not have the unique value duplicated
211-
cy.get('[data-cy="ncTable"] table').contains('unique-value-123').should('have.length', 1)
181+
// Verify that cloning fails due to unique constraint
182+
cy.get('.toastify.toast-error').should('be.visible').and('contain', 'Could not duplicate row')
212183
})
213184
})

cypress/support/commands.js

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ Cypress.Commands.add('createSelectionMultiColumn', (title, options, defaultOptio
288288
cy.get('.custom-table table tr th .cell').contains(title).should('exist')
289289
})
290290

291-
Cypress.Commands.add('createTextLineColumn', (title, defaultValue, maxLength, isFirstColumn) => {
291+
Cypress.Commands.add('createTextLineColumn', (title, defaultValue, maxLength, isFirstColumn, isUnique = false) => {
292292
cy.openCreateColumnModal(isFirstColumn)
293293
cy.get('[data-cy="columnTypeFormInput"]').clear().type(title)
294294
if (defaultValue) {
@@ -297,6 +297,9 @@ Cypress.Commands.add('createTextLineColumn', (title, defaultValue, maxLength, is
297297
if (maxLength) {
298298
cy.get('[data-cy="TextLineForm"] input').eq(1).type(maxLength)
299299
}
300+
if (isUnique) {
301+
cy.get('[data-cy="textLineUniqueSwitch"] input[type="checkbox"]').check({ force: true })
302+
}
300303
cy.get('.modal-container button').contains('Save').click()
301304
cy.wait(10).get('.toastify.toast-success').should('be.visible')
302305
cy.get('.custom-table table tr th .cell').contains(title).should('exist')
@@ -501,6 +504,83 @@ Cypress.Commands.add('removeColumn', (title) => {
501504
cy.get('[data-cy="confirmDialog"] button').contains('Confirm').click()
502505
})
503506

507+
Cypress.Commands.add('createTestRow', (tableName, rowData) => {
508+
cy.loadTable(tableName)
509+
cy.get('[data-cy="createRowBtn"]').click({ force: true })
510+
511+
if (rowData.text) {
512+
cy.get('[data-cy="createRowModal"] .slot input').first().type(rowData.text)
513+
}
514+
515+
if (rowData.description) {
516+
cy.get('[data-cy="createRowModal"] .ProseMirror').first().click()
517+
cy.get('[data-cy="createRowModal"] .ProseMirror').first().clear()
518+
cy.get('[data-cy="createRowModal"] .ProseMirror').first().type(rowData.description)
519+
}
520+
521+
if (rowData.stars) {
522+
for (let i = 0; i < rowData.stars; i++) {
523+
cy.get('[data-cy="createRowModal"] [aria-label="Increase stars"]').click()
524+
}
525+
}
526+
527+
cy.get('[data-cy="createRowSaveButton"]').click()
528+
cy.get('[data-cy="createRowModal"]').should('not.exist')
529+
530+
if (rowData.text) {
531+
cy.get('[data-cy="ncTable"] table').contains(rowData.text).should('exist')
532+
}
533+
})
534+
535+
Cypress.Commands.add('editRowInline', (originalText, newText) => {
536+
cy.get('[data-cy="ncTable"] [data-cy="customTableRow"]')
537+
.contains(originalText)
538+
.click()
539+
540+
cy.get('[data-cy="ncTable"] [data-cy="customTableRow"] .cell-input input').click()
541+
cy.get('.cell-input input').should('be.visible')
542+
cy.get('.cell-input input').should('have.focus')
543+
cy.get('.cell-input input').clear().type(`${newText}{enter}`)
544+
545+
cy.get('.icon-loading-small').should('not.exist')
546+
cy.get('[data-cy="ncTable"] table').contains(newText).should('exist')
547+
cy.get('[data-cy="ncTable"] table').contains(originalText).should('not.exist')
548+
})
549+
550+
Cypress.Commands.add('deleteRowByText', (rowText) => {
551+
cy.get('[data-cy="ncTable"] [data-cy="customTableRow"]').contains(rowText).closest('[data-cy="customTableRow"]').within(() => {
552+
cy.get('[data-cy="tableRowActions"]').click()
553+
})
554+
cy.get('[data-cy="deleteRowBtn"]').click()
555+
cy.get('[data-cy="deleteRowsConfirmation"] button').contains('Confirm').click()
556+
cy.get('.icon-loading').should('not.exist')
557+
cy.get('[data-cy="ncTable"] table').contains(rowText).should('not.exist')
558+
})
559+
560+
Cypress.Commands.add('duplicateRowByText', (rowText) => {
561+
cy.get('[data-cy="ncTable"] [data-cy="customTableRow"]').contains(rowText).closest('[data-cy="customTableRow"]').within(() => {
562+
cy.get('[data-cy="tableRowActions"]').click()
563+
})
564+
cy.get('[data-cy="duplicateRowBtn"]').click()
565+
cy.get('.icon-loading').should('not.exist')
566+
})
567+
568+
Cypress.Commands.add('cleanupTestTables', () => {
569+
const testTableNames = [
570+
'to do list',
571+
'Unique Test Table',
572+
'Test Table'
573+
]
574+
575+
testTableNames.forEach(tableName => {
576+
cy.get('body').then($body => {
577+
if ($body.find(`[data-cy="navigationTableItem"]:contains("${tableName}")`).length > 0) {
578+
cy.deleteTable(tableName)
579+
}
580+
})
581+
})
582+
})
583+
504584
// fill in a value in the 'create row' or 'edit row' model
505585
Cypress.Commands.add('fillInValueTextLine', (columnTitle, value) => {
506586
cy.get('.modal__content [data-cy="' + columnTitle + '"] .slot input').type(value)

src/modules/modals/DeleteRows.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
confirm-class="error"
99
:title="n('tables', 'Delete row', 'Delete rows', rowsToDelete.length, {})"
1010
:description="n('tables', 'Are you sure you want to delete the selected row?', 'Are you sure you want to delete the %n selected rows?', rowsToDelete.length, {})"
11+
data-cy="deleteRowsConfirmation"
1112
@confirm="deleteRows"
1213
@cancel="$emit('cancel')" />
1314
</div>

src/shared/components/ncTable/partials/TableRow.vue

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@
3030
<Fullscreen :size="20" />
3131
</template>
3232
</NcButton>
33-
<NcActions v-if="config.canDeleteRows || config.canCreateRows">
33+
<NcActions v-if="config.canDeleteRows || config.canCreateRows"
34+
:force-menu="true"
35+
:aria-label="t('tables', 'Row actions')"
36+
data-cy="tableRowActions">
3437
<NcActionButton v-if="config.canCreateRows"
3538
:close-after-click="true"
3639
data-cy="duplicateRowBtn"
@@ -60,7 +63,7 @@ import Fullscreen from 'vue-material-design-icons/Fullscreen.vue'
6063
import { mapActions } from 'pinia'
6164
import { useDataStore } from '../../../../store/data.js'
6265
import { NcCheckboxRadioSwitch, NcButton, NcActions, NcActionButton } from '@nextcloud/vue'
63-
import { getDialogBuilder, showError, showSuccess, DialogSeverity } from '@nextcloud/dialogs'
66+
import { showError, showSuccess } from '@nextcloud/dialogs'
6467
import Pencil from 'vue-material-design-icons/Pencil.vue'
6568
import ContentCopy from 'vue-material-design-icons/ContentCopy.vue'
6669
import Delete from 'vue-material-design-icons/Delete.vue'
@@ -82,6 +85,7 @@ import {
8285
TYPE_META_ID, TYPE_META_CREATED_BY, TYPE_META_CREATED_AT, TYPE_META_UPDATED_BY, TYPE_META_UPDATED_AT,
8386
} from '../../../../shared/constants.ts'
8487
import activityMixin from '../../../mixins/activityMixin.js'
88+
import { emit } from '@nextcloud/event-bus'
8589
8690
export default {
8791
name: 'TableRow',
@@ -232,28 +236,8 @@ export default {
232236
}
233237
},
234238
...mapActions(useDataStore, ['removeRow', 'insertNewRow']),
235-
async handleDeleteRow() {
236-
await getDialogBuilder(t('tables', 'Delete row'))
237-
.setText(t('tables', 'Are you sure you want to delete this row?'))
238-
.setSeverity(DialogSeverity.Warning)
239-
.addButton({
240-
label: t('tables', 'Delete'),
241-
type: 'error',
242-
callback: async () => {
243-
const res = await this.removeRow({
244-
rowId: this.row.id,
245-
isView: this.isView,
246-
elementId: this.elementId,
247-
})
248-
if (!res) {
249-
showError(t('tables', 'Could not delete row.'))
250-
} else {
251-
showSuccess(t('tables', 'Row deleted successfully.'))
252-
}
253-
},
254-
})
255-
.build()
256-
.show()
239+
handleDeleteRow() {
240+
emit('tables:row:delete', { rows: [this.row.id], isView: this.isView, elementId: this.elementId })
257241
},
258242
async handleCloneRow() {
259243
const data = this.row.data.reduce((acc, curr) => {
@@ -273,7 +257,7 @@ export default {
273257
data,
274258
})
275259
if (!res) {
276-
showError(t('tables', 'Could not clone row.'))
260+
showError(t('tables', 'Could not duplicate row.'))
277261
} else {
278262
showSuccess(t('tables', 'Row duplicated successfully.'))
279263
}

src/shared/components/ncTable/partials/columnTypePartials/forms/TextLineForm.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
{{ t('tables', 'Unique value') }}
4747
</div>
4848
<div class="fix-col-4 margin-bottom">
49-
<NcCheckboxRadioSwitch type="switch" :checked.sync="mutableColumn.textUnique" />
49+
<NcCheckboxRadioSwitch type="switch" :checked.sync="mutableColumn.textUnique" data-cy="textLineUniqueSwitch" />
5050
</div>
5151
</div>
5252
</div>

0 commit comments

Comments
 (0)