From d8b2fe55835e2dfe773733f3d55b3130614f1208 Mon Sep 17 00:00:00 2001 From: nabim777 Date: Wed, 22 Apr 2026 10:05:44 +0545 Subject: [PATCH 1/2] test: convert remaining link feature file into playwright only Signed-off-by: nabim777 --- .drone.star | 14 - .../specs/file-action/fileViewer.spec.ts | 14 +- .../specs/navigation/shortcut.spec.ts | 6 +- .../specs/navigation/urlJourneys.spec.ts | 6 +- tests/e2e-playwright/specs/ocm/ocm.spec.ts | 4 +- .../e2e-playwright/specs/shares/link.spec.ts | 935 ++++++++++++++++++ .../specs/spaces/publicLink.spec.ts | 8 +- tests/e2e-playwright/steps/ui/links.ts | 119 +++ tests/e2e-playwright/steps/ui/public.ts | 9 +- tests/e2e-playwright/steps/ui/resources.ts | 2 +- tests/e2e-playwright/steps/ui/shares.ts | 12 + .../e2e/cucumber/features/shares/link.feature | 258 ----- .../cucumber/features/shares/web-packages.txt | 9 - .../support/objects/app-files/link/actions.ts | 40 + .../objects/app-files/page/shares/viaLink.ts | 11 + 15 files changed, 1144 insertions(+), 303 deletions(-) delete mode 100644 tests/e2e/cucumber/features/shares/link.feature delete mode 100644 tests/e2e/cucumber/features/shares/web-packages.txt diff --git a/.drone.star b/.drone.star index 70498a2524d..f25cb8903df 100644 --- a/.drone.star +++ b/.drone.star @@ -77,20 +77,6 @@ config = { "spaces", ], }, - "3": { - "earlyFail": True, - "skip": False, - "tikaNeeded": True, - "suites": [ - "shares", - ], - "extraServerEnvironment": { - "FRONTEND_FULL_TEXT_SEARCH_ENABLED": True, - "SEARCH_EXTRACTOR_TYPE": "tika", - "SEARCH_EXTRACTOR_TIKA_TIKA_URL": "http://tika:9998", - "SEARCH_EXTRACTOR_CS3SOURCE_INSECURE": True, - }, - }, "keycloak": { "earlyFail": True, "skip": False, diff --git a/tests/e2e-playwright/specs/file-action/fileViewer.spec.ts b/tests/e2e-playwright/specs/file-action/fileViewer.spec.ts index 76623b2c01a..e88307f0259 100644 --- a/tests/e2e-playwright/specs/file-action/fileViewer.spec.ts +++ b/tests/e2e-playwright/specs/file-action/fileViewer.spec.ts @@ -96,7 +96,7 @@ test.describe('Different file viewers', { tag: '@predefined-users' }, () => { }) // Then "Alice" is in a media-viewer - await ui.userIsInFileViewer({ + await ui.userShouldBeInFileViewer({ world, stepUser: 'Alice', fileViewerType: 'media-viewer' @@ -116,7 +116,7 @@ test.describe('Different file viewers', { tag: '@predefined-users' }, () => { }) // Then "Alice" is in a media-viewer - await ui.userIsInFileViewer({ + await ui.userShouldBeInFileViewer({ world, stepUser: 'Alice', fileViewerType: 'media-viewer' @@ -150,7 +150,7 @@ test.describe('Different file viewers', { tag: '@predefined-users' }, () => { }) // Then "Alice" is in a media-viewer - await ui.userIsInFileViewer({ + await ui.userShouldBeInFileViewer({ world, stepUser: 'Alice', fileViewerType: 'media-viewer' @@ -170,7 +170,7 @@ test.describe('Different file viewers', { tag: '@predefined-users' }, () => { }) // Then "Alice" is in a media-viewer - await ui.userIsInFileViewer({ + await ui.userShouldBeInFileViewer({ world, stepUser: 'Alice', fileViewerType: 'media-viewer' @@ -190,7 +190,7 @@ test.describe('Different file viewers', { tag: '@predefined-users' }, () => { }) // Then "Alice" is in a media-viewer - await ui.userIsInFileViewer({ + await ui.userShouldBeInFileViewer({ world, stepUser: 'Alice', fileViewerType: 'media-viewer' @@ -210,7 +210,7 @@ test.describe('Different file viewers', { tag: '@predefined-users' }, () => { }) // Then "Alice" is in a media-viewer - await ui.userIsInFileViewer({ + await ui.userShouldBeInFileViewer({ world, stepUser: 'Alice', fileViewerType: 'media-viewer' @@ -230,7 +230,7 @@ test.describe('Different file viewers', { tag: '@predefined-users' }, () => { }) // Then "Alice" is in a media-viewer - await ui.userIsInFileViewer({ + await ui.userShouldBeInFileViewer({ world, stepUser: 'Alice', fileViewerType: 'media-viewer' diff --git a/tests/e2e-playwright/specs/navigation/shortcut.spec.ts b/tests/e2e-playwright/specs/navigation/shortcut.spec.ts index fc7df376aa2..5008b4eb694 100644 --- a/tests/e2e-playwright/specs/navigation/shortcut.spec.ts +++ b/tests/e2e-playwright/specs/navigation/shortcut.spec.ts @@ -115,7 +115,7 @@ test.describe( name: 'important file.url' }) // Then "Alice" is in a text-editor - await ui.userIsInFileViewer({ + await ui.userShouldBeInFileViewer({ world, stepUser: 'Alice', fileViewerType: 'text-editor' @@ -150,7 +150,7 @@ test.describe( name: 'logo.url' }) // Then "Brian" is in a media-viewer - await ui.userIsInFileViewer({ + await ui.userShouldBeInFileViewer({ world, stepUser: 'Brian', fileViewerType: 'media-viewer' @@ -182,7 +182,7 @@ test.describe( stepUser: 'Brian' }) // Then "Brian" is in a text-editor - await ui.userIsInFileViewer({ + await ui.userShouldBeInFileViewer({ world, stepUser: 'Brian', fileViewerType: 'text-editor' diff --git a/tests/e2e-playwright/specs/navigation/urlJourneys.spec.ts b/tests/e2e-playwright/specs/navigation/urlJourneys.spec.ts index 3e7f4c63ca6..1e49f5dc898 100644 --- a/tests/e2e-playwright/specs/navigation/urlJourneys.spec.ts +++ b/tests/e2e-playwright/specs/navigation/urlJourneys.spec.ts @@ -137,7 +137,7 @@ test.describe('Navigate web directly through urls', () => { }) // Then "Alice" is in a text-editor - await ui.userIsInFileViewer({ + await ui.userShouldBeInFileViewer({ world, stepUser: 'Alice', fileViewerType: 'text-editor' @@ -182,7 +182,7 @@ test.describe('Navigate web directly through urls', () => { application: 'texteditor' }) // Then "Alice" is in a text-editor - await ui.userIsInFileViewer({ + await ui.userShouldBeInFileViewer({ world, stepUser: 'Alice', fileViewerType: 'text-editor' @@ -205,7 +205,7 @@ test.describe('Navigate web directly through urls', () => { application: 'texteditor' }) // Then "Alice" is in a text-editor - await ui.userIsInFileViewer({ + await ui.userShouldBeInFileViewer({ world, stepUser: 'Alice', fileViewerType: 'text-editor' diff --git a/tests/e2e-playwright/specs/ocm/ocm.spec.ts b/tests/e2e-playwright/specs/ocm/ocm.spec.ts index 310d0096f47..c8fd525bac7 100644 --- a/tests/e2e-playwright/specs/ocm/ocm.spec.ts +++ b/tests/e2e-playwright/specs/ocm/ocm.spec.ts @@ -211,7 +211,7 @@ test.describe('federation management', { tag: '@ocm' }, async () => { }) // Then "Brian" is in a media-viewer - await ui.userIsInFileViewer({ + await ui.userShouldBeInFileViewer({ world, stepUser: 'Brian', fileViewerType: 'media-viewer' @@ -280,7 +280,7 @@ test.describe('federation management', { tag: '@ocm' }, async () => { }) // Then "Brian" is in a media-viewer - await ui.userIsInFileViewer({ + await ui.userShouldBeInFileViewer({ world, stepUser: 'Brian', fileViewerType: 'media-viewer' diff --git a/tests/e2e-playwright/specs/shares/link.spec.ts b/tests/e2e-playwright/specs/shares/link.spec.ts index b4969ec5f5a..21e9575f312 100644 --- a/tests/e2e-playwright/specs/shares/link.spec.ts +++ b/tests/e2e-playwright/specs/shares/link.spec.ts @@ -286,4 +286,939 @@ test.describe('link', () => { // And "Alice" logs out await ui.userLogsOut({ world, stepUser: 'Alice' }) }) + + test( + 'public link for folder and file (by authenticated user)', + { tag: '@predefined-users' }, + async ({ world }) => { + // Given "Admin" creates following user using API + // | id | + // | Brian | + // | Carol | + await api.usersHaveBeenCreated({ + world, + stepUser: 'Admin', + users: ['Brian', 'Carol'] + }) + + // And "Alice" logs in + await ui.userLogsIn({ world, stepUser: 'Alice' }) + // And "Alice" creates the following folders in personal space using API + // | name | + // | folderPublic | + await api.userHasCreatedFolders({ + world, + stepUser: 'Alice', + folderNames: ['folderPublic'] + }) + // And "Alice" creates the following files into personal space using API + // | pathToFile | content | + // | folderPublic/shareToBrian.txt | some text | + // | folderPublic/shareToBrian.md | readme | + await api.userHasCreatedFiles({ + world, + stepUser: 'Alice', + files: [ + { pathToFile: 'folderPublic/shareToBrian.txt', content: 'some text' }, + { pathToFile: 'folderPublic/shareToBrian.md', content: 'readme' } + ] + }) + // And "Alice" uploads the following local file into personal space using API + // | localFile | to | + // | filesForUpload/simple.pdf | simple.pdf | + // | filesForUpload/testavatar.jpg | testavatar.jpg | + // | filesForUpload/test_video.mp4 | test_video.mp4 | + await api.userHasUploadedFilesInPersonalSpace({ + world, + stepUser: 'Alice', + filesToUpload: [ + { localFile: 'filesForUpload/simple.pdf', to: 'simple.pdf' }, + { localFile: 'filesForUpload/testavatar.jpg', to: 'testavatar.jpg' }, + { localFile: 'filesForUpload/test_video.mp4', to: 'test_video.mp4' } + ] + }) + + // And "Alice" shares the following resource using API + // | resource | recipient | type | role | + // | folderPublic | Brian | user | Can edit | + // | simple.pdf | Brian | user | Can edit | + // | testavatar.jpg | Brian | user | Can edit | + await api.userHasSharedResources({ + world, + stepUser: 'Alice', + shares: [ + { + resource: 'folderPublic', + recipient: 'Brian', + type: 'user', + role: 'Can edit', + resourceType: 'folder' + }, + { + resource: 'simple.pdf', + recipient: 'Brian', + type: 'user', + role: 'Can edit', + resourceType: 'file' + }, + { + resource: 'testavatar.jpg', + recipient: 'Brian', + type: 'user', + role: 'Can edit', + resourceType: 'file' + } + ] + }) + + // And "Alice" opens the "files" app + await ui.userOpensApplication({ + world, + stepUser: 'Alice', + name: 'files' + }) + + // And "Alice" creates a public link of following resource using the sidebar panel + // | resource | password | + // | folderPublic | %public% | + await ui.userCreatesPublicLink({ + world, + stepUser: 'Alice', + resource: 'folderPublic', + password: '%public%' + }) + // And "Alice" renames the most recently created public link of resource "folderPublic" to "folderLink" + await ui.userRenamesMostRecentlyCreatedPublicLinkOfResource({ + world, + stepUser: 'Alice', + resource: 'folderPublic', + newName: 'folderLink' + }) + // And "Alice" creates a public link of following resource using the sidebar panel + // | resource | password | + // | folderPublic/shareToBrian.txt | %public% | + await ui.userCreatesPublicLink({ + world, + stepUser: 'Alice', + resource: 'folderPublic/shareToBrian.txt', + password: '%public%' + }) + // And "Alice" renames the most recently created public link of resource "folderPublic/shareToBrian.txt" to "textLink" + await ui.userRenamesMostRecentlyCreatedPublicLinkOfResource({ + world, + stepUser: 'Alice', + resource: 'folderPublic/shareToBrian.txt', + newName: 'textLink' + }) + // And "Alice" creates a public link of following resource using the sidebar panel + // | resource | password | + // | folderPublic/shareToBrian.md | %public% | + await ui.userCreatesPublicLink({ + world, + stepUser: 'Alice', + resource: 'folderPublic/shareToBrian.md', + password: '%public%' + }) + // And "Alice" renames the most recently created public link of resource "folderPublic/shareToBrian.md" to "markdownLink" + await ui.userRenamesMostRecentlyCreatedPublicLinkOfResource({ + world, + stepUser: 'Alice', + resource: 'folderPublic/shareToBrian.md', + newName: 'markdownLink' + }) + // And "Alice" creates a public link of following resource using the sidebar panel + // | resource | password | + // | simple.pdf | %public% | + await ui.userCreatesPublicLink({ + world, + stepUser: 'Alice', + resource: 'simple.pdf', + password: '%public%' + }) + // And "Alice" renames the most recently created public link of resource "simple.pdf" to "pdfLink" + await ui.userRenamesMostRecentlyCreatedPublicLinkOfResource({ + world, + stepUser: 'Alice', + resource: 'simple.pdf', + newName: 'pdfLink' + }) + // And "Alice" creates a public link of following resource using the sidebar panel + // | resource | password | + // | testavatar.jpg | %public% | + await ui.userCreatesPublicLink({ + world, + stepUser: 'Alice', + resource: 'testavatar.jpg', + password: '%public%' + }) + // And "Alice" renames the most recently created public link of resource "testavatar.jpg" to "imageLink" + await ui.userRenamesMostRecentlyCreatedPublicLinkOfResource({ + world, + stepUser: 'Alice', + resource: 'testavatar.jpg', + newName: 'imageLink' + }) + // And "Alice" creates a public link of following resource using the sidebar panel + // | resource | password | + // | test_video.mp4 | %public% | + await ui.userCreatesPublicLink({ + world, + stepUser: 'Alice', + resource: 'test_video.mp4', + password: '%public%' + }) + // And "Alice" renames the most recently created public link of resource "test_video.mp4" to "videoLink" + await ui.userRenamesMostRecentlyCreatedPublicLinkOfResource({ + world, + stepUser: 'Alice', + resource: 'test_video.mp4', + newName: 'videoLink' + }) + // And "Alice" logs out + await ui.userLogsOut({ world, stepUser: 'Alice' }) + + // authenticated user with access to resources. should be redirected to shares with me page + // And "Brian" logs in + await ui.userLogsIn({ world, stepUser: 'Brian' }) + // When "Brian" opens the public link "folderLink" + await ui.userOpensPublicLink({ + world, + stepUser: 'Brian', + name: 'folderLink' + }) + // And "Brian" unlocks the public link with password "%public%" + await ui.userUnlocksPublicLink({ + world, + password: '%public%', + stepUser: 'Brian' + }) + // And "Brian" downloads the following public link resources using the sidebar panel + // | resource | type | + // | shareToBrian.txt | file | + await ui.userDownloadsThePublicLinkResources({ + world, + stepUser: 'Brian', + actionType: 'SIDEBAR_PANEL', + resources: [{ resource: 'shareToBrian.txt', type: 'file' }] + }) + // And "Brian" uploads the following resources + // | resource | + // | lorem.txt | + await ui.userUploadsResourcesInPublicLink({ + world, + stepUser: 'Brian', + resources: [{ name: 'lorem.txt' }] + }) + // When "Brian" opens the public link "textLink" + await ui.userOpensPublicLink({ + world, + stepUser: 'Brian', + name: 'textLink' + }) + // And "Brian" unlocks the public link with password "%public%" + await ui.userUnlocksPublicLink({ + world, + stepUser: 'Brian', + password: '%public%' + }) + // Then "Brian" is in a text-editor + await ui.userShouldBeInFileViewer({ + world, + stepUser: 'Brian', + fileViewerType: 'text-editor' + }) + + // And "Brian" closes the file viewer + await ui.userClosesFileViewer({ world, stepUser: 'Brian' }) + // When "Brian" opens the public link "markdownLink" + await ui.userOpensPublicLink({ + world, + stepUser: 'Brian', + name: 'markdownLink' + }) + // And "Brian" unlocks the public link with password "%public%" + await ui.userUnlocksPublicLink({ + world, + password: '%public%', + stepUser: 'Brian' + }) + // Then "Brian" is in a text-editor + await ui.userShouldBeInFileViewer({ + world, + stepUser: 'Brian', + fileViewerType: 'text-editor' + }) + // And "Brian" closes the file viewer + await ui.userClosesFileViewer({ world, stepUser: 'Brian' }) + // And "Brian" downloads the following public link resources using the single share view + // | resource | type | + // | shareToBrian.md | file | + await ui.userDownloadsThePublicLinkResources({ + world, + stepUser: 'Brian', + actionType: 'SINGLE_SHARE_VIEW', + resources: [{ resource: 'shareToBrian.md', type: 'file' }] + }) + // When "Brian" opens the public link "pdfLink" + await ui.userOpensPublicLink({ + world, + stepUser: 'Brian', + name: 'pdfLink' + }) + // And "Brian" unlocks the public link with password "%public%" + await ui.userUnlocksPublicLink({ + world, + password: '%public%', + stepUser: 'Brian' + }) + // Then "Brian" is in a pdf-viewer + await ui.userShouldBeInFileViewer({ + world, + stepUser: 'Brian', + fileViewerType: 'pdf-viewer' + }) + // And "Brian" closes the file viewer + await ui.userClosesFileViewer({ world, stepUser: 'Brian' }) + // And "Brian" downloads the following public link resources using the single share view + // | resource | type | + // | simple.pdf | file | + await ui.userDownloadsThePublicLinkResources({ + world, + stepUser: 'Brian', + actionType: 'SINGLE_SHARE_VIEW', + resources: [{ resource: 'simple.pdf', type: 'file' }] + }) + // When "Brian" opens the public link "imageLink" + await ui.userOpensPublicLink({ + world, + stepUser: 'Brian', + name: 'imageLink' + }) + // And "Brian" unlocks the public link with password "%public%" + await ui.userUnlocksPublicLink({ + world, + password: '%public%', + stepUser: 'Brian' + }) + // https://github.com/owncloud/ocis/issues/8602 + // Then "Brian" is in a media-viewer + await ui.userShouldBeInFileViewer({ + world, + stepUser: 'Brian', + fileViewerType: 'media-viewer' + }) + // And "Brian" closes the file viewer + await ui.userClosesFileViewer({ world, stepUser: 'Brian' }) + // And "Brian" downloads the following public link resources using the single share view + // | resource | type | + // | testavatar.jpg | file | + await ui.userDownloadsThePublicLinkResources({ + world, + stepUser: 'Brian', + actionType: 'SINGLE_SHARE_VIEW', + resources: [{ resource: 'testavatar.jpg', type: 'file' }] + }) + // And "Brian" logs out + await ui.userLogsOut({ world, stepUser: 'Brian' }) + + // authenticated user without access to resources. should be redirected to the public links page + // And "Carol" logs in + await ui.userLogsIn({ world, stepUser: 'Carol' }) + // When "Carol" opens the public link "folderLink" + await ui.userOpensPublicLink({ + world, + stepUser: 'Carol', + name: 'folderLink' + }) + // And "Carol" unlocks the public link with password "%public%" + await ui.userUnlocksPublicLink({ + world, + password: '%public%', + stepUser: 'Carol' + }) + // https://github.com/owncloud/web/issues/10473 + // And "Carol" downloads the following public link resources using the sidebar panel + // | resource | type | + // | lorem.txt | file | + await ui.userDownloadsThePublicLinkResources({ + world, + stepUser: 'Carol', + actionType: 'SIDEBAR_PANEL', + resources: [{ resource: 'lorem.txt', type: 'file' }] + }) + // When "Carol" opens the public link "textLink" + await ui.userOpensPublicLink({ + world, + stepUser: 'Carol', + name: 'textLink' + }) + // And "Carol" unlocks the public link with password "%public%" + await ui.userUnlocksPublicLink({ + world, + password: '%public%', + stepUser: 'Carol' + }) + // Then "Carol" is in a text-editor + await ui.userShouldBeInFileViewer({ + world, + stepUser: 'Carol', + fileViewerType: 'text-editor' + }) + // And "Carol" closes the file viewer + await ui.userClosesFileViewer({ world, stepUser: 'Carol' }) + // When "Carol" opens the public link "markdownLink" + await ui.userOpensPublicLink({ + world, + stepUser: 'Carol', + name: 'markdownLink' + }) + // And "Carol" unlocks the public link with password "%public%" + await ui.userUnlocksPublicLink({ + world, + password: '%public%', + stepUser: 'Carol' + }) + // Then "Carol" is in a text-editor + await ui.userShouldBeInFileViewer({ + world, + stepUser: 'Carol', + fileViewerType: 'text-editor' + }) + // And "Carol" closes the file viewer + await ui.userClosesFileViewer({ world, stepUser: 'Carol' }) + // And "Carol" downloads the following public link resources using the single share view + // | resource | type | + // | shareToBrian.md | file | + await ui.userDownloadsThePublicLinkResources({ + world, + stepUser: 'Carol', + actionType: 'SINGLE_SHARE_VIEW', + resources: [{ resource: 'shareToBrian.md', type: 'file' }] + }) + // When "Carol" opens the public link "pdfLink" + await ui.userOpensPublicLink({ + world, + stepUser: 'Carol', + name: 'pdfLink' + }) + // And "Carol" unlocks the public link with password "%public%" + await ui.userUnlocksPublicLink({ + world, + password: '%public%', + stepUser: 'Carol' + }) + // Then "Carol" is in a pdf-viewer + await ui.userShouldBeInFileViewer({ + world, + stepUser: 'Carol', + fileViewerType: 'pdf-viewer' + }) + // And "Carol" closes the file viewer + await ui.userClosesFileViewer({ world, stepUser: 'Carol' }) + // And "Carol" downloads the following public link resources using the single share view + // | resource | type | + // | simple.pdf | file | + await ui.userDownloadsThePublicLinkResources({ + world, + stepUser: 'Carol', + actionType: 'SINGLE_SHARE_VIEW', + resources: [{ resource: 'simple.pdf', type: 'file' }] + }) + // When "Carol" opens the public link "imageLink" + await ui.userOpensPublicLink({ + world, + stepUser: 'Carol', + name: 'imageLink' + }) + // And "Carol" unlocks the public link with password "%public%" + await ui.userUnlocksPublicLink({ + world, + password: '%public%', + stepUser: 'Carol' + }) + // https://github.com/owncloud/ocis/issues/8602 + // Then "Carol" is in a media-viewer + await ui.userShouldBeInFileViewer({ + world, + stepUser: 'Carol', + fileViewerType: 'media-viewer' + }) + // And "Carol" closes the file viewer + await ui.userClosesFileViewer({ world, stepUser: 'Carol' }) + // And "Carol" downloads the following public link resources using the single share view + // | resource | type | + // | testavatar.jpg | file | + await ui.userDownloadsThePublicLinkResources({ + world, + stepUser: 'Carol', + actionType: 'SINGLE_SHARE_VIEW', + resources: [{ resource: 'testavatar.jpg', type: 'file' }] + }) + // And "Carol" logs out + await ui.userLogsOut({ world, stepUser: 'Carol' }) + + // Anonymous user + // When "Anonymous" opens the public link "folderLink" + await ui.userOpensPublicLink({ + world, + stepUser: 'Anonymous', + name: 'folderLink' + }) + // And "Anonymous" unlocks the public link with password "%public%" + await ui.userUnlocksPublicLink({ + world, + password: '%public%', + stepUser: 'Anonymous' + }) + // And "Anonymous" downloads the following public link resources using the sidebar panel + // | resource | type | + // | lorem.txt | file | + await ui.userDownloadsThePublicLinkResources({ + world, + stepUser: 'Anonymous', + actionType: 'SIDEBAR_PANEL', + resources: [{ resource: 'lorem.txt', type: 'file' }] + }) + // When "Anonymous" opens the public link "textLink" + await ui.userOpensPublicLink({ + world, + stepUser: 'Anonymous', + name: 'textLink' + }) + // And "Anonymous" unlocks the public link with password "%public%" + await ui.userUnlocksPublicLink({ + world, + password: '%public%', + stepUser: 'Anonymous' + }) + // Then "Anonymous" is in a text-editor + await ui.userShouldBeInFileViewer({ + world, + stepUser: 'Anonymous', + fileViewerType: 'text-editor' + }) + // And "Anonymous" closes the file viewer + await ui.userClosesFileViewer({ world, stepUser: 'Anonymous' }) + // When "Anonymous" opens the public link "markdownLink" + await ui.userOpensPublicLink({ + world, + stepUser: 'Anonymous', + name: 'markdownLink' + }) + // And "Anonymous" unlocks the public link with password "%public%" + await ui.userUnlocksPublicLink({ + world, + password: '%public%', + stepUser: 'Anonymous' + }) + // Then "Anonymous" is in a text-editor + await ui.userShouldBeInFileViewer({ + world, + stepUser: 'Anonymous', + fileViewerType: 'text-editor' + }) + // And "Anonymous" closes the file viewer + await ui.userClosesFileViewer({ world, stepUser: 'Anonymous' }) + // And "Anonymous" downloads the following public link resources using the single share view + // | resource | type | + // | shareToBrian.md | file | + await ui.userDownloadsThePublicLinkResources({ + world, + stepUser: 'Anonymous', + actionType: 'SINGLE_SHARE_VIEW', + resources: [{ resource: 'shareToBrian.md', type: 'file' }] + }) + // When "Anonymous" opens the public link "pdfLink" + await ui.userOpensPublicLink({ + world, + stepUser: 'Anonymous', + name: 'pdfLink' + }) + // And "Anonymous" unlocks the public link with password "%public%" + await ui.userUnlocksPublicLink({ + world, + password: '%public%', + stepUser: 'Anonymous' + }) + // Then "Anonymous" is in a pdf-viewer + await ui.userShouldBeInFileViewer({ + world, + stepUser: 'Anonymous', + fileViewerType: 'pdf-viewer' + }) + // And "Anonymous" closes the file viewer + await ui.userClosesFileViewer({ world, stepUser: 'Anonymous' }) + // And "Anonymous" downloads the following public link resources using the single share view + // | resource | type | + // | simple.pdf | file | + await ui.userDownloadsThePublicLinkResources({ + world, + stepUser: 'Anonymous', + actionType: 'SINGLE_SHARE_VIEW', + resources: [{ resource: 'simple.pdf', type: 'file' }] + }) + // When "Anonymous" opens the public link "imageLink" + await ui.userOpensPublicLink({ + world, + stepUser: 'Anonymous', + name: 'imageLink' + }) + // And "Anonymous" unlocks the public link with password "%public% + await ui.userUnlocksPublicLink({ + world, + password: '%public%', + stepUser: 'Anonymous' + }) + // https://github.com/owncloud/ocis/issues/8602 + // Then "Anonymous" is in a media-viewer + await ui.userShouldBeInFileViewer({ + world, + stepUser: 'Anonymous', + fileViewerType: 'media-viewer' + }) + // And "Anonymous" closes the file viewer + await ui.userClosesFileViewer({ world, stepUser: 'Anonymous' }) + // And "Anonymous" downloads the following public link resources using the single share view + // | resource | type | + // | testavatar.jpg | file | + await ui.userDownloadsThePublicLinkResources({ + world, + stepUser: 'Anonymous', + actionType: 'SINGLE_SHARE_VIEW', + resources: [{ resource: 'testavatar.jpg', type: 'file' }] + }) + // When "Anonymous" opens the public link "videoLink" + await ui.userOpensPublicLink({ + world, + stepUser: 'Anonymous', + name: 'videoLink' + }) + // And "Anonymous" unlocks the public link with password "%public%" + await ui.userUnlocksPublicLink({ + world, + password: '%public%', + stepUser: 'Anonymous' + }) + // Then "Anonymous" is in a media-viewer + await ui.userShouldBeInFileViewer({ + world, + stepUser: 'Anonymous', + fileViewerType: 'media-viewer' + }) + // And "Anonymous" closes the file viewer + await ui.userClosesFileViewer({ world, stepUser: 'Anonymous' }) + } + ) + + test('add banned password for public link', async ({ world }) => { + // When "Alice" logs in + await ui.userLogsIn({ world, stepUser: 'Alice' }) + // And "Alice" creates the following files into personal space using API + // | pathToFile | content | + // | lorem.txt | some text | + await api.userHasCreatedFiles({ + world, + stepUser: 'Alice', + files: [{ pathToFile: 'lorem.txt', content: 'some text' }] + }) + + // And "Alice" opens the "files" app + await ui.userOpensApplication({ + world, + stepUser: 'Alice', + name: 'files' + }) + // And "Alice" creates a public link of following resource using the sidebar panel + // | resource | password | + // | lorem.txt | %public% | + await ui.userCreatesPublicLink({ + world, + stepUser: 'Alice', + resource: 'lorem.txt', + password: '%public%' + }) + // When "Alice" tries to sets a new password "ownCloud-1" of the public link named "Unnamed link" of resource "lorem.txt" + await ui.userChangesPasswordOfThePublicLinkOfResource({ + world, + stepUser: 'Alice', + resource: 'lorem.txt', + linkName: 'Unnamed link', + newPassword: 'ownCloud-1' + }) + // Then "Alice" should see an error message + // """ + // Unfortunately, your password is commonly used. please pick a harder-to-guess password for your safety + // """ + await ui.userShouldSeeAnErrorMessage({ + world, + stepUser: 'Alice', + errorMessage: + 'Unfortunately, your password is commonly used. please pick a harder-to-guess password for your safety' + }) + // And "Alice" closes the public link password dialog box + await ui.userClosesThePublicLinkPasswordDialogBox({ + world, + stepUser: 'Alice' + }) + // When "Alice" tries to sets a new password "12345678" of the public link named "Unnamed link" of resource "lorem.txt" + await ui.userChangesPasswordOfThePublicLinkOfResource({ + world, + stepUser: 'Alice', + resource: 'lorem.txt', + linkName: 'Unnamed link', + newPassword: '12345678' + }) + // Then "Alice" should see an error message + // """ + // Unfortunately, your password is commonly used. please pick a harder-to-guess password for your safety + // """ + await ui.userShouldSeeAnErrorMessage({ + world, + stepUser: 'Alice', + errorMessage: + 'Unfortunately, your password is commonly used. please pick a harder-to-guess password for your safety' + }) + // And "Alice" reveals the password of the public link + await ui.userRevealsThePasswordOfThePublicLink({ + world, + stepUser: 'Alice' + }) + // And "Alice" hides the password of the public link + await ui.userHidesThePasswordOfThePublicLink({ + world, + stepUser: 'Alice' + }) + // And "Alice" generates the password for the public link + await ui.userGeneratesThePasswordForThePublicLink({ + world, + stepUser: 'Alice' + }) + // And "Alice" copies the password of the public link + await ui.userCopiesThePasswordOfThePublicLink({ + world, + stepUser: 'Alice' + }) + // And "Alice" sets the password of the public link + await ui.userSetsThePasswordOfThePublicLink({ + world, + stepUser: 'Alice' + }) + // And "Anonymous" opens the public link "Unnamed link" + await ui.userOpensPublicLink({ + world, + stepUser: 'Anonymous', + name: 'Unnamed link' + }) + // And "Anonymous" unlocks the public link with password "%copied_password%" + await ui.userUnlocksPublicLink({ + world, + password: '%copied_password%', + stepUser: 'Anonymous' + }) + // And "Alice" logs out + await ui.userLogsOut({ world, stepUser: 'Alice' }) + }) + + test('edit password of the public link', { tag: '@predefined-users' }, async ({ world }) => { + // When "Alice" logs in + await ui.userLogsIn({ world, stepUser: 'Alice' }) + // And "Alice" creates the following folders in personal space using API + // | name | + // | folderPublic | + await api.userHasCreatedFolders({ + world, + stepUser: 'Alice', + folderNames: ['folderPublic'] + }) + // And "Alice" creates the following files into personal space using API + // | pathToFile | content | + // | folderPublic/lorem.txt | lorem ipsum | + await api.userHasCreatedFiles({ + world, + stepUser: 'Alice', + files: [{ pathToFile: 'folderPublic/lorem.txt', content: 'lorem ipsum' }] + }) + // And "Alice" opens the "files" app + await ui.userOpensApplication({ + world, + stepUser: 'Alice', + name: 'files' + }) + // And "Alice" creates a public link of following resource using the sidebar panel + // | resource | role | password | + // | folderPublic | Can edit | %public% | + await ui.userCreatesPublicLink({ + world, + stepUser: 'Alice', + resource: 'folderPublic', + password: '%public%', + role: 'Can edit' + }) + // And "Alice" renames the most recently created public link of resource "folderPublic" to "myPublicLink" + await ui.userRenamesMostRecentlyCreatedPublicLinkOfResource({ + world, + stepUser: 'Alice', + resource: 'folderPublic', + newName: 'myPublicLink' + }) + // When "Anonymous" opens the public link "myPublicLink" + await ui.userOpensPublicLink({ + world, + stepUser: 'Anonymous', + name: 'myPublicLink' + }) + // And "Anonymous" unlocks the public link with password "%public%" + await ui.userUnlocksPublicLink({ + world, + password: '%public%', + stepUser: 'Anonymous' + }) + // And "Alice" changes the password of the public link named "myPublicLink" of resource "folderPublic" to "new-strongPass1" + await ui.userChangesPasswordOfThePublicLinkOfResource({ + world, + stepUser: 'Alice', + resource: 'folderPublic', + linkName: 'myPublicLink', + newPassword: 'new-strongPass1' + }) + // And "Anonymous" refreshes the old link + await ui.userRefreshesTheOldLink({ + world, + stepUser: 'Anonymous' + }) + // And "Anonymous" unlocks the public link with password "new-strongPass1" + await ui.userUnlocksPublicLink({ + world, + password: 'new-strongPass1', + stepUser: 'Anonymous' + }) + // And "Anonymous" downloads the following public link resources using the sidebar panel + // | resource | type | + // | lorem.txt | file | + await ui.userDownloadsThePublicLinkResources({ + world, + stepUser: 'Anonymous', + actionType: 'SIDEBAR_PANEL', + resources: [{ resource: 'lorem.txt', type: 'file' }] + }) + // And "Alice" logs out + await ui.userLogsOut({ world, stepUser: 'Alice' }) + }) + + test('link indication', { tag: '@predefined-users' }, async ({ world }) => { + // When "Alice" logs in + await ui.userLogsIn({ world, stepUser: 'Alice' }) + // And "Alice" creates the following folders in personal space using API + // | name | + // | folderPublic | + await api.userHasCreatedFolders({ + world, + stepUser: 'Alice', + folderNames: ['folderPublic'] + }) + // And "Alice" creates the following files into personal space using API + // | pathToFile | content | + // | folderPublic/lorem.txt | lorem ipsum | + await api.userHasCreatedFiles({ + world, + stepUser: 'Alice', + files: [{ pathToFile: 'folderPublic/lorem.txt', content: 'lorem ipsum' }] + }) + // And "Alice" opens the "files" app + await ui.userOpensApplication({ + world, + stepUser: 'Alice', + name: 'files' + }) + // And "Alice" creates a public link of following resource using the sidebar panel + // | resource | role | password | + // | folderPublic | Can edit | %public% | + await ui.userCreatesPublicLink({ + world, + stepUser: 'Alice', + resource: 'folderPublic', + password: '%public%', + role: 'Can edit' + }) + // When "Alice" opens the "files" app + await ui.userOpensApplication({ + world, + stepUser: 'Alice', + name: 'files' + }) + // And "Alice" closes the sidebar + await ui.userClosesSidebar({ world, stepUser: 'Alice' }) + // Then "Alice" should see link-direct indicator on the folder "folderPublic" + await ui.userShouldSeeShareIndicatorOnResource({ + world, + stepUser: 'Alice', + buttonLabel: 'link-direct', + resource: 'folderPublic' + }) + + // When "Alice" opens folder "folderPublic" + await ui.userOpensResource({ + world, + stepUser: 'Alice', + resource: 'folderPublic' + }) + // Then "Alice" should see link-indirect indicator on the file "lorem.txt" + await ui.userShouldSeeShareIndicatorOnResource({ + world, + stepUser: 'Alice', + buttonLabel: 'link-indirect', + resource: 'lorem.txt' + }) + + // And "Alice" navigates to the shared via link page + await ui.userNavigatesToSharedViaLinkPage({ world, stepUser: 'Alice' }) + // Then following resources should be displayed in the files list for user "Alice" + // | resource | + // | folderPublic | + await ui.userShouldSeeResources({ + world, + listType: 'files list', + stepUser: 'Alice', + resources: ['folderPublic'] + }) + + // check copy link to clipboard button + // When "Alice" opens the "files" app + await ui.userOpensApplication({ + world, + stepUser: 'Alice', + name: 'files' + }) + // And "Alice" copies the link "Unnamed link" of resource "folderPublic" + await ui.userCopiesLinkOfResource({ + world, + stepUser: 'Alice', + resource: 'folderPublic' + }) + + // And "Alice" opens the "%clipboard%" url + await ui.userOpensClipboardUrl({ + world, + stepUser: 'Alice', + url: '%clipboard%' + }) + // And "Alice" unlocks the public link with password "%public%" + await ui.userUnlocksPublicLink({ + world, + password: '%public%', + stepUser: 'Alice' + }) + // Then following resources should be displayed in the files list for user "Alice" + // | resource | + // | lorem.txt | + await ui.userShouldSeeResources({ + world, + listType: 'files list', + stepUser: 'Alice', + resources: ['lorem.txt'] + }) + + // And "Alice" logs out + await ui.userLogsOut({ world, stepUser: 'Alice' }) + }) }) diff --git a/tests/e2e-playwright/specs/spaces/publicLink.spec.ts b/tests/e2e-playwright/specs/spaces/publicLink.spec.ts index f3e22f7be39..8a8a86cbcd5 100644 --- a/tests/e2e-playwright/specs/spaces/publicLink.spec.ts +++ b/tests/e2e-playwright/specs/spaces/publicLink.spec.ts @@ -181,7 +181,7 @@ test.describe('spaces public link', () => { password: '%public%' }) - await ui.userIsInFileViewer({ + await ui.userShouldBeInFileViewer({ world, stepUser: 'Brian', fileViewerType: 'text-editor' @@ -204,7 +204,7 @@ test.describe('spaces public link', () => { password: '%public%' }) - await ui.userIsInFileViewer({ + await ui.userShouldBeInFileViewer({ world, stepUser: 'Brian', fileViewerType: 'text-editor' @@ -273,7 +273,7 @@ test.describe('spaces public link', () => { password: '%public%' }) - await ui.userIsInFileViewer({ + await ui.userShouldBeInFileViewer({ world, stepUser: 'Carol', fileViewerType: 'pdf-viewer' @@ -327,7 +327,7 @@ test.describe('spaces public link', () => { password: '%public%' }) - await ui.userIsInFileViewer({ + await ui.userShouldBeInFileViewer({ world, stepUser: 'David', fileViewerType: 'media-viewer' diff --git a/tests/e2e-playwright/steps/ui/links.ts b/tests/e2e-playwright/steps/ui/links.ts index 0b10fef84f6..a2f5260b9eb 100644 --- a/tests/e2e-playwright/steps/ui/links.ts +++ b/tests/e2e-playwright/steps/ui/links.ts @@ -163,3 +163,122 @@ export async function userShouldNotBeAbleToEditThePublicLink({ const isVisible = await linkObject.islinkEditButtonVisibile(linkName) expect(isVisible).toBe(false) } + +export async function userChangesPasswordOfThePublicLinkOfResource({ + world, + stepUser, + resource, + linkName, + newPassword +}: { + world: World + stepUser: string + resource: string + linkName: string + newPassword: string +}): Promise { + const { page } = world.actorsEnvironment.getActor({ key: stepUser }) + const linkObject = new objects.applicationFiles.Link({ page }) + await linkObject.fillPassword({ resource, linkName, newPassword }) +} + +export async function userShouldSeeAnErrorMessage({ + world, + stepUser, + errorMessage +}: { + world: World + stepUser: string + errorMessage: string +}): Promise { + const { page } = world.actorsEnvironment.getActor({ key: stepUser }) + const linkObject = new objects.applicationFiles.Link({ page }) + const actualErrorMessage = await linkObject.checkErrorMessage() + expect(actualErrorMessage).toBe(errorMessage) +} + +export async function userClosesThePublicLinkPasswordDialogBox({ + world, + stepUser +}: { + world: World + stepUser: string +}): Promise { + const { page } = world.actorsEnvironment.getActor({ key: stepUser }) + const linkObject = new objects.applicationFiles.Link({ page }) + await linkObject.clickOnCancelButton() +} + +export async function userRevealsThePasswordOfThePublicLink({ + world, + stepUser +}: { + world: World + stepUser: string +}): Promise { + const { page } = world.actorsEnvironment.getActor({ key: stepUser }) + const linkObject = new objects.applicationFiles.Link({ page }) + await linkObject.showOrHidePassword({ showOrHide: 'reveals' }) +} + +export async function userHidesThePasswordOfThePublicLink({ + world, + stepUser +}: { + world: World + stepUser: string +}): Promise { + const { page } = world.actorsEnvironment.getActor({ key: stepUser }) + const linkObject = new objects.applicationFiles.Link({ page }) + await linkObject.showOrHidePassword({ showOrHide: 'hides' }) +} + +export async function userGeneratesThePasswordForThePublicLink({ + world, + stepUser +}: { + world: World + stepUser: string +}): Promise { + const { page } = world.actorsEnvironment.getActor({ key: stepUser }) + const linkObject = new objects.applicationFiles.Link({ page }) + await linkObject.generatePassword() +} + +export async function userCopiesThePasswordOfThePublicLink({ + world, + stepUser +}: { + world: World + stepUser: string +}): Promise { + const { page } = world.actorsEnvironment.getActor({ key: stepUser }) + const linkObject = new objects.applicationFiles.Link({ page }) + await linkObject.copyEnteredPassword() +} + +export async function userSetsThePasswordOfThePublicLink({ + world, + stepUser +}: { + world: World + stepUser: string +}): Promise { + const { page } = world.actorsEnvironment.getActor({ key: stepUser }) + const linkObject = new objects.applicationFiles.Link({ page }) + await linkObject.setPassword() +} + +export async function userCopiesLinkOfResource({ + world, + stepUser, + resource +}: { + world: World + stepUser: string + resource: string +}): Promise { + const { page } = world.actorsEnvironment.getActor({ key: stepUser }) + const linkObject = new objects.applicationFiles.Link({ page }) + await linkObject.copyLinkToClipboard({ resource }) +} diff --git a/tests/e2e-playwright/steps/ui/public.ts b/tests/e2e-playwright/steps/ui/public.ts index b24f3284d24..bc2a7f5535d 100644 --- a/tests/e2e-playwright/steps/ui/public.ts +++ b/tests/e2e-playwright/steps/ui/public.ts @@ -76,7 +76,12 @@ export async function userUnlocksPublicLink({ }): Promise { const { page } = world.actorsEnvironment.getActor({ key: stepUser }) const pageObject = new objects.applicationFiles.page.Public({ page }) - await pageObject.authenticate({ password: substitute(password) }) + if (password === '%copied_password%') { + password = await page.evaluate('navigator.clipboard.readText()') + } else { + password = substitute(password) + } + await pageObject.authenticate({ password }) } export async function userUploadsResourcesInPublicLink({ @@ -122,7 +127,7 @@ export async function userDeletesResourcesFromPublicLink({ } } -export async function userIsInFileViewer({ +export async function userShouldBeInFileViewer({ world, stepUser, fileViewerType diff --git a/tests/e2e-playwright/steps/ui/resources.ts b/tests/e2e-playwright/steps/ui/resources.ts index 09b106756e8..afa2615374e 100644 --- a/tests/e2e-playwright/steps/ui/resources.ts +++ b/tests/e2e-playwright/steps/ui/resources.ts @@ -1128,7 +1128,7 @@ export async function userDownloadsThePublicLinkResources({ }: { world: World stepUser: string - actionType: 'SIDEBAR_PANEL' | 'BATCH_ACTION' + actionType: 'SIDEBAR_PANEL' | 'BATCH_ACTION' | 'SINGLE_SHARE_VIEW' resources: resourceToDownload[] }): Promise { const { page } = world.actorsEnvironment.getActor({ key: stepUser }) diff --git a/tests/e2e-playwright/steps/ui/shares.ts b/tests/e2e-playwright/steps/ui/shares.ts index ecacda11462..83fd6c6988a 100644 --- a/tests/e2e-playwright/steps/ui/shares.ts +++ b/tests/e2e-playwright/steps/ui/shares.ts @@ -492,3 +492,15 @@ export async function userShouldSeeMessageOnWebUI({ const actualMessage = await shareObject.getMessage() expect(actualMessage).toBe(message) } + +export async function userNavigatesToSharedViaLinkPage({ + world, + stepUser +}: { + world: World + stepUser: string +}): Promise { + const { page } = world.actorsEnvironment.getActor({ key: stepUser }) + const pageObject = new objects.applicationFiles.page.shares.ViaLink({ page }) + await pageObject.navigate() +} diff --git a/tests/e2e/cucumber/features/shares/link.feature b/tests/e2e/cucumber/features/shares/link.feature deleted file mode 100644 index 3c80c03ddd2..00000000000 --- a/tests/e2e/cucumber/features/shares/link.feature +++ /dev/null @@ -1,258 +0,0 @@ -Feature: link - - Background: - Given "Admin" creates following user using API - | id | - | Alice | - - @predefined-users - Scenario: public link for folder and file (by authenticated user) - Given "Admin" creates following user using API - | id | - | Brian | - | Carol | - And "Alice" logs in - And "Brian" logs in - And "Alice" creates the following folders in personal space using API - | name | - | folderPublic | - And "Alice" creates the following files into personal space using API - | pathToFile | content | - | folderPublic/shareToBrian.txt | some text | - | folderPublic/shareToBrian.md | readme | - And "Alice" uploads the following local file into personal space using API - | localFile | to | - | filesForUpload/simple.pdf | simple.pdf | - | filesForUpload/testavatar.jpg | testavatar.jpg | - | filesForUpload/test_video.mp4 | test_video.mp4 | - And "Alice" shares the following resource using API - | resource | recipient | type | role | resourceType | - | folderPublic | Brian | user | Can edit | folder | - | simple.pdf | Brian | user | Can edit | file | - | testavatar.jpg | Brian | user | Can edit | file | - - And "Alice" opens the "files" app - And "Alice" creates a public link of following resource using the sidebar panel - | resource | password | - | folderPublic | %public% | - And "Alice" renames the most recently created public link of resource "folderPublic" to "folderLink" - And "Alice" creates a public link of following resource using the sidebar panel - | resource | password | - | folderPublic/shareToBrian.txt | %public% | - And "Alice" renames the most recently created public link of resource "folderPublic/shareToBrian.txt" to "textLink" - And "Alice" creates a public link of following resource using the sidebar panel - | resource | password | - | folderPublic/shareToBrian.md | %public% | - And "Alice" renames the most recently created public link of resource "folderPublic/shareToBrian.md" to "markdownLink" - And "Alice" creates a public link of following resource using the sidebar panel - | resource | password | - | simple.pdf | %public% | - And "Alice" renames the most recently created public link of resource "simple.pdf" to "pdfLink" - And "Alice" creates a public link of following resource using the sidebar panel - | resource | password | - | testavatar.jpg | %public% | - And "Alice" renames the most recently created public link of resource "testavatar.jpg" to "imageLink" - And "Alice" creates a public link of following resource using the sidebar panel - | resource | password | - | test_video.mp4 | %public% | - And "Alice" renames the most recently created public link of resource "test_video.mp4" to "videoLink" - And "Alice" logs out - - # authenticated user with access to resources. should be redirected to shares with me page - When "Brian" opens the public link "folderLink" - And "Brian" unlocks the public link with password "%public%" - And "Brian" downloads the following public link resources using the sidebar panel - | resource | type | - | shareToBrian.txt | file | - And "Brian" uploads the following resources - | resource | - | lorem.txt | - When "Brian" opens the public link "textLink" - And "Brian" unlocks the public link with password "%public%" - Then "Brian" is in a text-editor - And "Brian" closes the file viewer - When "Brian" opens the public link "markdownLink" - And "Brian" unlocks the public link with password "%public%" - Then "Brian" is in a text-editor - And "Brian" closes the file viewer - And "Brian" downloads the following public link resources using the single share view - | resource | type | - | shareToBrian.md | file | - When "Brian" opens the public link "pdfLink" - And "Brian" unlocks the public link with password "%public%" - Then "Brian" is in a pdf-viewer - And "Brian" closes the file viewer - And "Brian" downloads the following public link resources using the single share view - | resource | type | - | simple.pdf | file | - When "Brian" opens the public link "imageLink" - And "Brian" unlocks the public link with password "%public%" - # https://github.com/owncloud/ocis/issues/8602 - Then "Brian" is in a media-viewer - And "Brian" closes the file viewer - And "Brian" downloads the following public link resources using the single share view - | resource | type | - | testavatar.jpg | file | - And "Brian" logs out - - # authenticated user without access to resources. should be redirected to the public links page - And "Carol" logs in - When "Carol" opens the public link "folderLink" - And "Carol" unlocks the public link with password "%public%" - # https://github.com/owncloud/web/issues/10473 - And "Carol" downloads the following public link resources using the sidebar panel - | resource | type | - | lorem.txt | file | - When "Carol" opens the public link "textLink" - And "Carol" unlocks the public link with password "%public%" - Then "Carol" is in a text-editor - And "Carol" closes the file viewer - When "Carol" opens the public link "markdownLink" - And "Carol" unlocks the public link with password "%public%" - Then "Carol" is in a text-editor - And "Carol" closes the file viewer - And "Carol" downloads the following public link resources using the single share view - | resource | type | - | shareToBrian.md | file | - When "Carol" opens the public link "pdfLink" - And "Carol" unlocks the public link with password "%public%" - Then "Carol" is in a pdf-viewer - And "Carol" closes the file viewer - And "Carol" downloads the following public link resources using the single share view - | resource | type | - | simple.pdf | file | - When "Carol" opens the public link "imageLink" - And "Carol" unlocks the public link with password "%public%" - # https://github.com/owncloud/ocis/issues/8602 - Then "Carol" is in a media-viewer - And "Carol" closes the file viewer - And "Carol" downloads the following public link resources using the single share view - | resource | type | - | testavatar.jpg | file | - And "Carol" logs out - - # Anonymous user - When "Anonymous" opens the public link "folderLink" - And "Anonymous" unlocks the public link with password "%public%" - And "Anonymous" downloads the following public link resources using the sidebar panel - | resource | type | - | lorem.txt | file | - When "Anonymous" opens the public link "textLink" - And "Anonymous" unlocks the public link with password "%public%" - Then "Anonymous" is in a text-editor - And "Anonymous" closes the file viewer - When "Anonymous" opens the public link "markdownLink" - And "Anonymous" unlocks the public link with password "%public%" - Then "Anonymous" is in a text-editor - And "Anonymous" closes the file viewer - And "Anonymous" downloads the following public link resources using the single share view - | resource | type | - | shareToBrian.md | file | - When "Anonymous" opens the public link "pdfLink" - And "Anonymous" unlocks the public link with password "%public%" - Then "Anonymous" is in a pdf-viewer - And "Anonymous" closes the file viewer - And "Anonymous" downloads the following public link resources using the single share view - | resource | type | - | simple.pdf | file | - When "Anonymous" opens the public link "imageLink" - And "Anonymous" unlocks the public link with password "%public%" - # https://github.com/owncloud/ocis/issues/8602 - Then "Anonymous" is in a media-viewer - And "Anonymous" closes the file viewer - And "Anonymous" downloads the following public link resources using the single share view - | resource | type | - | testavatar.jpg | file | - When "Anonymous" opens the public link "videoLink" - And "Anonymous" unlocks the public link with password "%public%" - Then "Anonymous" is in a media-viewer - And "Anonymous" closes the file viewer - - - Scenario: add banned password for public link - When "Alice" logs in - And "Alice" creates the following files into personal space using API - | pathToFile | content | - | lorem.txt | some text | - - And "Alice" opens the "files" app - And "Alice" creates a public link of following resource using the sidebar panel - | resource | password | - | lorem.txt | %public% | - When "Alice" tries to sets a new password "ownCloud-1" of the public link named "Unnamed link" of resource "lorem.txt" - Then "Alice" should see an error message - """ - Unfortunately, your password is commonly used. please pick a harder-to-guess password for your safety - """ - And "Alice" closes the public link password dialog box - When "Alice" tries to sets a new password "ownCloud-1" of the public link named "Unnamed link" of resource "lorem.txt" - Then "Alice" should see an error message - """ - Unfortunately, your password is commonly used. please pick a harder-to-guess password for your safety - """ - And "Alice" reveals the password of the public link - And "Alice" hides the password of the public link - And "Alice" generates the password for the public link - And "Alice" copies the password of the public link - And "Alice" sets the password of the public link - And "Anonymous" opens the public link "Unnamed link" - And "Anonymous" unlocks the public link with password "%copied_password%" - And "Alice" logs out - - @predefined-users - Scenario: edit password of the public link - When "Alice" logs in - And "Alice" creates the following folders in personal space using API - | name | - | folderPublic | - And "Alice" creates the following files into personal space using API - | pathToFile | content | - | folderPublic/lorem.txt | lorem ipsum | - And "Alice" opens the "files" app - And "Alice" creates a public link of following resource using the sidebar panel - | resource | role | password | - | folderPublic | Can edit | %public% | - And "Alice" renames the most recently created public link of resource "folderPublic" to "myPublicLink" - When "Anonymous" opens the public link "myPublicLink" - And "Anonymous" unlocks the public link with password "%public%" - And "Alice" changes the password of the public link named "myPublicLink" of resource "folderPublic" to "new-strongPass1" - And "Anonymous" refreshes the old link - And "Anonymous" unlocks the public link with password "new-strongPass1" - And "Anonymous" downloads the following public link resources using the sidebar panel - | resource | type | - | lorem.txt | file | - And "Alice" logs out - - @predefined-users - Scenario: link indication - When "Alice" logs in - And "Alice" creates the following folders in personal space using API - | name | - | folderPublic | - And "Alice" creates the following files into personal space using API - | pathToFile | content | - | folderPublic/lorem.txt | lorem ipsum | - And "Alice" opens the "files" app - And "Alice" creates a public link of following resource using the sidebar panel - | resource | role | password | - | folderPublic | Can edit | %public% | - When "Alice" opens the "files" app - And "Alice" closes the sidebar - Then "Alice" should see link-direct indicator on the folder "folderPublic" - When "Alice" opens folder "folderPublic" - Then "Alice" should see link-indirect indicator on the file "lorem.txt" - - And "Alice" navigates to the shared via link page - Then following resources should be displayed in the files list for user "Alice" - | resource | - | folderPublic | - - # check copy link to clipboard button - When "Alice" opens the "files" app - And "Alice" copies the link "Unnamed link" of resource "folderPublic" - And "Alice" opens the "%clipboard%" url - And "Alice" unlocks the public link with password "%public%" - Then following resources should be displayed in the files list for user "Alice" - | resource | - | lorem.txt | - And "Alice" logs out diff --git a/tests/e2e/cucumber/features/shares/web-packages.txt b/tests/e2e/cucumber/features/shares/web-packages.txt deleted file mode 100644 index 09ef0727e24..00000000000 --- a/tests/e2e/cucumber/features/shares/web-packages.txt +++ /dev/null @@ -1,9 +0,0 @@ -###################################################################### -# USED FOR CI ONLY # -# Run the test suite only if the changes are in the listed packages. # -# # -# List of web packages that affect this test suite. # -###################################################################### - -web-app-files -web-app-preview \ No newline at end of file diff --git a/tests/e2e/support/objects/app-files/link/actions.ts b/tests/e2e/support/objects/app-files/link/actions.ts index 2c5b99dd9d9..cfa38daf818 100644 --- a/tests/e2e/support/objects/app-files/link/actions.ts +++ b/tests/e2e/support/objects/app-files/link/actions.ts @@ -257,10 +257,30 @@ export const fillPassword = async (args: addPasswordArgs): Promise => { await clickResource({ page: page, path: resourcePaths.join('/') }) } await sidebar.open({ page: page, resource: resourceName }) + await objects.a11y.Accessibility.assertNoSevereA11yViolations( + page, + ['appSidebar'], + 'sidebar after opening the resource' + ) await sidebar.openPanel({ page: page, name: 'sharing' }) await page.locator(util.format(editPublicLinkButton, linkName)).click() + await objects.a11y.Accessibility.assertNoSevereA11yViolations( + page, + ['tippyBox'], + 'edit public link tippy box' + ) await page.locator(editPublicLinkAddPasswordButton).click() + await objects.a11y.Accessibility.assertNoSevereA11yViolations( + page, + ['ocModal'], + 'edit public link password modal' + ) await page.locator(editPublicLinkPasswordInput).fill(newPassword) + await objects.a11y.Accessibility.assertNoSevereA11yViolations( + page, + ['ocModal'], + 'edit public link password modal after filling password' + ) await page.locator(editPublicLinkRenameConfirm).click() } @@ -278,6 +298,11 @@ export const showOrHidePassword = async (args: { }): Promise => { const { page, showOrHide } = args await page.locator(showOrHidePasswordButton).click() + await objects.a11y.Accessibility.assertNoSevereA11yViolations( + page, + ['ocModal'], + `${showOrHide} password of public link modal` + ) showOrHide === 'reveals' ? await expect(page.locator(editPublicLinkPasswordInput)).toHaveAttribute('type', 'text') : await expect(page.locator(editPublicLinkPasswordInput)).toHaveAttribute('type', 'password') @@ -286,12 +311,22 @@ export const showOrHidePassword = async (args: { export const copyEnteredPassword = async (page: Page): Promise => { const enteredPassword = await page.locator(editPublicLinkPasswordInput).inputValue() await page.locator(copyPasswordButton).click() + await objects.a11y.Accessibility.assertNoSevereA11yViolations( + page, + ['ocModal'], + 'copy password of public link modal' + ) const copiedPassword = await page.evaluate('navigator.clipboard.readText()') expect(enteredPassword).toBe(copiedPassword) } export const generatePassword = async (page: Page): Promise => { await page.locator(generatePasswordButton).click() + await objects.a11y.Accessibility.assertNoSevereA11yViolations( + page, + ['ocModal'], + 'generate password for public link modal' + ) const generatedPassword = await page.locator(editPublicLinkPasswordInput).inputValue() expect(generatedPassword).toMatch(expectedRegexForGeneratedPassword) } @@ -451,6 +486,11 @@ export const copyLinkToClipboard = async (args: copyLinkArgs): Promise = } else { await page.getByLabel('Copy link to clipboard').click() } + await objects.a11y.Accessibility.assertNoSevereA11yViolations( + page, + ['.snackbar'], + 'copy link to clipboard notification' + ) return await page.evaluate('navigator.clipboard.readText()') } diff --git a/tests/e2e/support/objects/app-files/page/shares/viaLink.ts b/tests/e2e/support/objects/app-files/page/shares/viaLink.ts index 01f69312676..47950125050 100644 --- a/tests/e2e/support/objects/app-files/page/shares/viaLink.ts +++ b/tests/e2e/support/objects/app-files/page/shares/viaLink.ts @@ -1,4 +1,5 @@ import { Page } from '@playwright/test' +import { objects } from '../../../..' const sharesNavSelector = '//a[@data-nav-name="files-shares"]' @@ -11,6 +12,16 @@ export class ViaLink { async navigate(): Promise { await this.#page.locator(sharesNavSelector).click() + await objects.a11y.Accessibility.assertNoSevereA11yViolations( + this.#page, + ['files', 'sidebarNavigationMenu'], + 'shares via link page after navigation' + ) await this.#page.getByText('Shared via link').click() + await objects.a11y.Accessibility.assertNoSevereA11yViolations( + this.#page, + ['filesView'], + 'shares via link page after clicking shared via link' + ) } } From 6860dc108c794650b085de3416853f293c8a0338 Mon Sep 17 00:00:00 2001 From: nabim777 Date: Thu, 23 Apr 2026 13:10:49 +0545 Subject: [PATCH 2/2] test: add password policy env Signed-off-by: nabim777 --- tests/actions/.env.ocis | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/actions/.env.ocis b/tests/actions/.env.ocis index 7ad315afc87..ac27586ffd5 100644 --- a/tests/actions/.env.ocis +++ b/tests/actions/.env.ocis @@ -130,3 +130,9 @@ AUTH_BASIC_LDAP_BIND_PASSWORD=some-ldap-reva-password IDM_IDPSVC_PASSWORD=some-ldap-idp-password IDP_LDAP_BIND_PASSWORD=some-ldap-idp-password GRAPH_APPLICATION_ID=application-1 +OCIS_PASSWORD_POLICY_BANNED_PASSWORDS_LIST="$GITHUB_WORKSPACE/tests/drone/banned-passwords.txt" +OCIS_PASSWORD_POLICY_MIN_CHARACTERS=3 +OCIS_PASSWORD_POLICY_MIN_LOWERCASE_CHARACTERS=0 +OCIS_PASSWORD_POLICY_MIN_UPPERCASE_CHARACTERS=0 +OCIS_PASSWORD_POLICY_MIN_DIGITS=0 +OCIS_PASSWORD_POLICY_MIN_SPECIAL_CHARACTERS=0 \ No newline at end of file