drag-n-drop.cy.ts 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /**
  2. * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
  3. * SPDX-License-Identifier: AGPL-3.0-or-later
  4. */
  5. import { getRowForFile } from './FilesUtils.ts'
  6. describe('files: Drag and Drop', { testIsolation: true }, () => {
  7. beforeEach(() => {
  8. cy.createRandomUser().then((user) => {
  9. cy.login(user)
  10. })
  11. cy.visit('/apps/files')
  12. })
  13. it('can drop a file', () => {
  14. const dataTransfer = new DataTransfer()
  15. dataTransfer.items.add(new File([], 'single-file.txt'))
  16. cy.intercept('PUT', /\/remote.php\/dav\/files\//).as('uploadFile')
  17. // Make sure the drop notice is not visible
  18. cy.get('[data-cy-files-drag-drop-area]').should('not.be.visible')
  19. // Trigger the drop notice
  20. cy.get('main.app-content').trigger('dragover', { dataTransfer })
  21. cy.get('[data-cy-files-drag-drop-area]').should('be.visible')
  22. // Upload drop a file
  23. cy.get('[data-cy-files-drag-drop-area]').selectFile({
  24. fileName: 'single-file.txt',
  25. contents: ['hello '.repeat(1024)],
  26. }, { action: 'drag-drop' })
  27. cy.wait('@uploadFile')
  28. // Make sure the upload is finished
  29. cy.get('[data-cy-files-drag-drop-area]').should('not.be.visible')
  30. cy.get('[data-cy-upload-picker] progress').should('not.be.visible')
  31. cy.get('@uploadFile.all').should('have.length', 1)
  32. getRowForFile('single-file.txt').should('be.visible')
  33. getRowForFile('single-file.txt').find('[data-cy-files-list-row-size]').should('contain', '6 KB')
  34. })
  35. it('can drop multiple files', () => {
  36. const dataTransfer = new DataTransfer()
  37. dataTransfer.items.add(new File([], 'first.txt'))
  38. dataTransfer.items.add(new File([], 'second.txt'))
  39. cy.intercept('PUT', /\/remote.php\/dav\/files\//).as('uploadFile')
  40. // Make sure the drop notice is not visible
  41. cy.get('[data-cy-files-drag-drop-area]').should('not.be.visible')
  42. // Trigger the drop notice
  43. cy.get('main.app-content').trigger('dragover', { dataTransfer })
  44. cy.get('[data-cy-files-drag-drop-area]').should('be.visible')
  45. // Upload drop a file
  46. cy.get('[data-cy-files-drag-drop-area]').selectFile([
  47. {
  48. fileName: 'first.txt',
  49. contents: ['Hello'],
  50. },
  51. {
  52. fileName: 'second.txt',
  53. contents: ['World'],
  54. },
  55. ], { action: 'drag-drop' })
  56. cy.wait('@uploadFile')
  57. // Make sure the upload is finished
  58. cy.get('[data-cy-files-drag-drop-area]').should('not.be.visible')
  59. cy.get('[data-cy-upload-picker] progress').should('not.be.visible')
  60. cy.get('@uploadFile.all').should('have.length', 2)
  61. getRowForFile('first.txt').should('be.visible')
  62. getRowForFile('second.txt').should('be.visible')
  63. })
  64. it('will ignore legacy Folders', () => {
  65. cy.window().then((win) => {
  66. // Remove the Filesystem API to force the legacy File API
  67. // See how cypress mocks the Filesystem API in https://github.com/cypress-io/cypress/blob/74109094a92df3bef073dda15f17194f31850d7d/packages/driver/src/cy/commands/actions/selectFile.ts#L24-L37
  68. Object.defineProperty(win.DataTransferItem.prototype, 'getAsEntry', { get: undefined })
  69. Object.defineProperty(win.DataTransferItem.prototype, 'webkitGetAsEntry', { get: undefined })
  70. })
  71. const dataTransfer = new DataTransfer()
  72. dataTransfer.items.add(new File([], 'first.txt'))
  73. dataTransfer.items.add(new File([], 'second.txt'))
  74. // Legacy File API (not FileSystem API), will treat Folders as Files
  75. // with empty type and empty content
  76. dataTransfer.items.add(new File([], 'Foo', { type: 'httpd/unix-directory' }))
  77. dataTransfer.items.add(new File([], 'Bar'))
  78. cy.intercept('PUT', /\/remote.php\/dav\/files\//).as('uploadFile')
  79. // Make sure the drop notice is not visible
  80. cy.get('[data-cy-files-drag-drop-area]').should('not.be.visible')
  81. // Trigger the drop notice
  82. cy.get('main.app-content').trigger('dragover', { dataTransfer })
  83. cy.get('[data-cy-files-drag-drop-area]').should('be.visible')
  84. // Upload drop a file
  85. cy.get('[data-cy-files-drag-drop-area]').selectFile([
  86. {
  87. fileName: 'first.txt',
  88. contents: ['Hello'],
  89. },
  90. {
  91. fileName: 'second.txt',
  92. contents: ['World'],
  93. },
  94. {
  95. fileName: 'Foo',
  96. contents: {},
  97. },
  98. {
  99. fileName: 'Bar',
  100. contents: { mimeType: 'httpd/unix-directory' },
  101. },
  102. ], { action: 'drag-drop' })
  103. cy.wait('@uploadFile')
  104. // Make sure the upload is finished
  105. cy.get('[data-cy-files-drag-drop-area]').should('not.be.visible')
  106. cy.get('[data-cy-upload-picker] progress').should('not.be.visible')
  107. cy.get('@uploadFile.all').should('have.length', 2)
  108. getRowForFile('first.txt').should('be.visible')
  109. getRowForFile('second.txt').should('be.visible')
  110. getRowForFile('Foo').should('not.exist')
  111. getRowForFile('Bar').should('not.exist')
  112. })
  113. })