diff --git a/changelog/unreleased/enhancement-single-file-link-open-with-default-app b/changelog/unreleased/enhancement-single-file-link-open-with-default-app new file mode 100644 index 00000000000..f0b52a9929a --- /dev/null +++ b/changelog/unreleased/enhancement-single-file-link-open-with-default-app @@ -0,0 +1,7 @@ +Enhancement: Single file link open with default app + +We've added a configurable functionality, that a single shared file via link will be opened in default app, +for example text-editor. + +https://github.com/owncloud/web/pull/9046 +https://github.com/owncloud/web/issues/9045 diff --git a/docs/getting-started.md b/docs/getting-started.md index badf3a54641..0384b7ba899 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -1,5 +1,5 @@ --- -title: "Getting Started" +title: 'Getting Started' date: 2018-05-02T00:00:00+00:00 weight: 10 geekdocRepo: https://github.com/owncloud/web @@ -43,10 +43,11 @@ Depending on the backend you are using, there are sample config files provided i - `customTranslations` You can specify one or multiple files to overwrite existing translations. For example set this option to `[{url: "https://localhost:9200/customTranslations.json"}]`. #### Options + - `options.homeFolder` You can specify a folder that is used when the user navigates `home`. Navigating home gets triggered by clicking on the `All files` -menu item. The user will not be jailed in that directory. It simply serves as a default location. You can either provide a static location, or you can use -variables of the user object to come up with a user specific home path. This uses twig template variable style and allows you to pick a value or a -substring of a value of the authenticated user. Examples are `/Shares`, `/{{.Id}}` and `/{{substr 0 3 .Id}}/{{.Id}`. + menu item. The user will not be jailed in that directory. It simply serves as a default location. You can either provide a static location, or you can use + variables of the user object to come up with a user specific home path. This uses twig template variable style and allows you to pick a value or a + substring of a value of the authenticated user. Examples are `/Shares`, `/{{.Id}}` and `/{{substr 0 3 .Id}}/{{.Id}`. - `options.openAppsInTab` Configures whether apps and extensions generally should open in a new tab. Defaults to false. - `options.disablePreviews` Set this option to `true` to disable previews in all the different file listing views. The only list view that is not affected by this is the trash bin, as that doesn't allow showing previews at all. @@ -64,13 +65,14 @@ substring of a value of the authenticated user. Examples are `/Shares`, `/{{.Id} - `options.runningOnEos` Set this option to `true` if running on an [EOS storage backend](https://eos-web.web.cern.ch/eos-web/) to enable its specific features. Defaults to `false`. - `options.cernFeatures` Enabling this will activate CERN-specific features. Defaults to `false`. - `options.hoverableQuickActions` Set this option to `true` to hide the quick actions (buttons appearing on file rows), and only show them when the user -hovers the row with his mouse. Defaults to `false`. + hovers the row with his mouse. Defaults to `false`. - `option.routing` This accepts an object with the following fields to customize the routing behaviour: - - `options.routing.idBased` Enable or disable fileIds being added to the URL. Defaults to `true` because otherwise e.g. spaces with name clashes can't be resolved correctly. Only disable this if you can guarantee server side that spaces of the same namespace can't have name clashes. + - `options.routing.idBased` Enable or disable fileIds being added to the URL. Defaults to `true` because otherwise e.g. spaces with name clashes can't be resolved correctly. Only disable this if you can guarantee server side that spaces of the same namespace can't have name clashes. - `options.upload.xhr.timeout` Specifies the timeout for XHR uploads in milliseconds. - `options.editor.autosaveEnabled` Specifies if the autosave for the editor apps is enabled. - `options.editor.autosaveInterval` Specifies the time interval for the autosave of editor apps in seconds. - `options.contextHelpersReadMore` Specifies whether the "Read more" link should be displayed or not. +- `options.openLinksWithDefaultApp` Specifies whether single file link shares should be opened with default app or not. ### Sentry diff --git a/packages/web-app-files/src/components/FilesList/ResourceDetails.vue b/packages/web-app-files/src/components/FilesList/ResourceDetails.vue index 5b96dfe13ab..7f63a34b145 100644 --- a/packages/web-app-files/src/components/FilesList/ResourceDetails.vue +++ b/packages/web-app-files/src/components/FilesList/ResourceDetails.vue @@ -7,14 +7,16 @@ - - diff --git a/packages/web-app-files/src/composables/actions/files/useFileActions.ts b/packages/web-app-files/src/composables/actions/files/useFileActions.ts index ebc0a3fec40..d439691856e 100644 --- a/packages/web-app-files/src/composables/actions/files/useFileActions.ts +++ b/packages/web-app-files/src/composables/actions/files/useFileActions.ts @@ -34,6 +34,10 @@ import { export const EDITOR_MODE_EDIT = 'edit' export const EDITOR_MODE_CREATE = 'create' +export interface GetFileActionsOptions extends FileActionOptions { + omitSystemActions?: boolean +} + export const useFileActions = ({ store }: { store?: Store } = {}) => { store = store || useStore() const router = useRouter() @@ -214,7 +218,11 @@ export const useFileActions = ({ store }: { store?: Store } = {}) => { action.handler(options) } - const getDefaultAction = (options: FileActionOptions): Action => { + const getDefaultEditorAction = (options: FileActionOptions): Action | null => { + return getDefaultAction({ ...options, omitSystemActions: true }) + } + + const getDefaultAction = (options: GetFileActionsOptions): Action | null => { const filterCallback = (action) => action.canBeDefault && action.isEnabled({ @@ -236,7 +244,7 @@ export const useFileActions = ({ store }: { store?: Store } = {}) => { } // fallback: system actions - return unref(systemActions).filter(filterCallback)[0] + return options.omitSystemActions ? null : unref(systemActions).filter(filterCallback)[0] } const getAllAvailableActions = (options: FileActionOptions) => { @@ -323,6 +331,8 @@ export const useFileActions = ({ store }: { store?: Store } = {}) => { return { editorActions, systemActions, + getDefaultAction, + getDefaultEditorAction, getAllAvailableActions, loadExternalAppActions, openEditor, diff --git a/packages/web-app-files/src/views/spaces/GenericSpace.vue b/packages/web-app-files/src/views/spaces/GenericSpace.vue index 05d01e8ff88..4380fe19191 100644 --- a/packages/web-app-files/src/views/spaces/GenericSpace.vue +++ b/packages/web-app-files/src/views/spaces/GenericSpace.vue @@ -170,7 +170,7 @@ import AppLoadingSpinner from 'web-pkg/src/components/AppLoadingSpinner.vue' import NoContentMessage from 'web-pkg/src/components/NoContentMessage.vue' import WhitespaceContextMenu from 'web-app-files/src/components/Spaces/WhitespaceContextMenu.vue' import Pagination from 'web-pkg/src/components/Pagination.vue' -import { useRoute } from 'web-pkg/src/composables' +import { useRoute, useRouteQuery } from 'web-pkg/src/composables' import { useDocumentTitle } from 'web-pkg/src/composables/appDefaults/useDocumentTitle' import { ImageType } from 'web-pkg/src/constants' import { VisibilityObserver } from 'web-pkg/src/observer' @@ -231,6 +231,8 @@ export default defineComponent({ setup(props) { const store = useStore() const { $gettext, $ngettext, interpolate: $gettextInterpolate } = useGettext() + const { getDefaultEditorAction } = useFileActions() + const openWithDefaultAppQuery = useRouteQuery('openWithDefaultApp') let loadResourcesEventToken const canUpload = computed(() => { @@ -388,6 +390,25 @@ export default defineComponent({ } } + const openWithDefaultApp = () => { + const highlightedFile = store.getters['Files/highlightedFile'] + + if (!highlightedFile || highlightedFile.isFolder) { + return + } + + const fileActionsOptions = { + resources: [highlightedFile], + space: props.space + } + + const defaultEditorAction = getDefaultEditorAction(fileActionsOptions) + + if (defaultEditorAction) { + defaultEditorAction.handler({ ...fileActionsOptions }) + } + } + const resourcesViewDefaults = useResourcesViewDefaults() const performLoaderTask = async ( sameRoute: boolean, @@ -412,6 +433,10 @@ export default defineComponent({ ]) resourcesViewDefaults.refreshFileListHeaderPosition() focusAndAnnounceBreadcrumb(sameRoute) + + if (unref(openWithDefaultAppQuery) === 'true') { + openWithDefaultApp() + } } onMounted(() => { diff --git a/packages/web-app-files/tests/unit/components/FilesList/ResourceDetails.spec.ts b/packages/web-app-files/tests/unit/components/FilesList/ResourceDetails.spec.ts new file mode 100644 index 00000000000..f0a044292c0 --- /dev/null +++ b/packages/web-app-files/tests/unit/components/FilesList/ResourceDetails.spec.ts @@ -0,0 +1,90 @@ +import { + createStore, + defaultComponentMocks, + defaultPlugins, + defaultStoreMockOptions, + mount, + RouteLocation +} from 'web-test-helpers' +import ResourceDetails from '../../../../src/components/FilesList/ResourceDetails.vue' +import { mock } from 'jest-mock-extended' +import { useFileActions } from 'web-app-files/src/composables/actions/files/useFileActions' +import { SpaceResource } from 'web-client' +import { useRouteQuery } from 'web-pkg' +import { ref } from 'vue' + +jest.mock('web-app-files/src/composables/actions/files/useFileActions') +jest.mock('web-pkg/src/composables/router', () => ({ + ...jest.requireActual('web-pkg/src/composables/router'), + useRouteQuery: jest.fn() +})) + +describe('ResourceDetails component', () => { + jest.mocked(useFileActions).mockImplementation(() => + mock>({ + getDefaultEditorAction: () => ({ handler: jest.fn() } as any) + }) + ) + + it('renders resource details correctly', () => { + const { wrapper } = getWrapper() + expect(wrapper.html()).toMatchSnapshot() + }) + + describe('open with default actions', () => { + it("doesn't open default action if query param 'openWithDefaultApp' isn't set true", () => { + const { wrapper } = getWrapper() + expect(wrapper.vm.defaultEditorAction.handler).not.toHaveBeenCalled() + }) + it("opens default action if query param 'openWithDefaultApp' is set true", () => { + jest.mocked(useRouteQuery).mockImplementationOnce(() => ref('true')) + const { wrapper } = getWrapper() + expect(wrapper.vm.defaultEditorAction.handler).toHaveBeenCalled() + }) + }) + + function getWrapper() { + const mocks = { + ...defaultComponentMocks({ + currentRoute: mock({ + name: 'files-public-link', + query: { openWithDefaultAppQuery: 'true' } + }) + }) + } + const storeOptions = { ...defaultStoreMockOptions } + const store = createStore(storeOptions) + + const file = { + id: 0, + name: 'image.jpg', + size: 24064, + mdate: 'Wed, 21 Oct 2015 07:28:00 GMT', + mimeType: 'image/jpg', + owner: [ + { + username: 'admin' + } + ] + } + const space = mock() + + return { + mocks, + wrapper: mount(ResourceDetails, { + props: { + space, + singleResource: file + }, + global: { + mocks, + plugins: [...defaultPlugins(), store], + provide: { + space, + resource: file + } + } + }) + } + } +}) diff --git a/packages/web-app-files/tests/unit/components/FilesList/__snapshots__/ResourceDetails.spec.ts.snap b/packages/web-app-files/tests/unit/components/FilesList/__snapshots__/ResourceDetails.spec.ts.snap new file mode 100644 index 00000000000..37a901ff021 --- /dev/null +++ b/packages/web-app-files/tests/unit/components/FilesList/__snapshots__/ResourceDetails.spec.ts.snap @@ -0,0 +1,57 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ResourceDetails component renders resource details correctly 1`] = ` +
+
+
+
+ + + +
+

+ + image.jpg + + +

+
+
+ +
+
+
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + +
Last modified + Oct 21, 2015, 7:28 AM +
Size24 kB
+
+
+
    +
    +
    +`; diff --git a/packages/web-pkg/src/configuration/manager.ts b/packages/web-pkg/src/configuration/manager.ts index 89575a297f8..14cb596a9b8 100644 --- a/packages/web-pkg/src/configuration/manager.ts +++ b/packages/web-pkg/src/configuration/manager.ts @@ -89,6 +89,11 @@ export class ConfigurationManager { 'contextHelpersReadMore', get(options, 'contextHelpersReadMore', true) ) + set( + this.optionsConfiguration, + 'openLinksWithDefaultApp', + get(options, 'openLinksWithDefaultApp', true) + ) } get options(): OptionsConfiguration { diff --git a/packages/web-pkg/src/configuration/types.ts b/packages/web-pkg/src/configuration/types.ts index 51973be0f1d..721a56860aa 100644 --- a/packages/web-pkg/src/configuration/types.ts +++ b/packages/web-pkg/src/configuration/types.ts @@ -14,6 +14,7 @@ export interface OptionsConfiguration { routing?: RoutingOptionsConfiguration logoutUrl?: string contextHelpersReadMore?: boolean + openLinksWithDefaultApp?: boolean } export interface OAuth2Configuration { diff --git a/packages/web-runtime/src/pages/resolvePrivateLink.vue b/packages/web-runtime/src/pages/resolvePrivateLink.vue index 8a4808bd06d..c229f8a2122 100644 --- a/packages/web-runtime/src/pages/resolvePrivateLink.vue +++ b/packages/web-runtime/src/pages/resolvePrivateLink.vue @@ -148,7 +148,10 @@ export default defineComponent({ query: { ...query, scrollTo: unref(resource).fileId, - ...(unref(details) && { details: unref(details) }) + ...(unref(details) && { details: unref(details) }), + ...(configurationManager.options.openLinksWithDefaultApp && { + openWithDefaultApp: 'true' + }) } } router.push(location) diff --git a/packages/web-runtime/src/pages/resolvePublicLink.vue b/packages/web-runtime/src/pages/resolvePublicLink.vue index aff7690d329..a66d96eac89 100644 --- a/packages/web-runtime/src/pages/resolvePublicLink.vue +++ b/packages/web-runtime/src/pages/resolvePublicLink.vue @@ -65,6 +65,7 @@ import { authService } from '../services/auth' import { queryItemAsString, useClientService, + useConfigurationManager, useRouteParam, useRouteQuery, useRouter, @@ -86,6 +87,7 @@ import { useGettext } from 'vue3-gettext' export default defineComponent({ name: 'ResolvePublicLink', setup() { + const configurationManager = useConfigurationManager() const clientService = useClientService() const router = useRouter() const store = useStore() @@ -157,7 +159,11 @@ export default defineComponent({ return router.push({ name: 'resolvePrivateLink', params: { fileId: `${fileId}` }, - ...(unref(details) && { query: { details: unref(details) } }) + ...(unref(details) && { + query: { + details: unref(details) + } + }) }) } const resolvePublicLinkTask = useTask(function* (signal, passwordRequired: boolean) { @@ -192,6 +198,11 @@ export default defineComponent({ router.push({ name: 'files-public-link', + query: { + ...(configurationManager.options.openLinksWithDefaultApp && { + openWithDefaultApp: 'true' + }) + }, params: { driveAliasAndItem: `public/${unref(token)}` } }) }) diff --git a/packages/web-runtime/src/store/config.ts b/packages/web-runtime/src/store/config.ts index aece2d8efa7..bf1cf44db56 100644 --- a/packages/web-runtime/src/store/config.ts +++ b/packages/web-runtime/src/store/config.ts @@ -58,7 +58,8 @@ const state = { runningOnEos: false, cernFeatures: false, sharingRecipientsPerPage: 200, - contextHelpersReadMore: true + contextHelpersReadMore: true, + openLinksWithDefaultApp: true } } diff --git a/tests/acceptance/expected-failures-with-oc10-server-oauth2-login.md b/tests/acceptance/expected-failures-with-oc10-server-oauth2-login.md index af897d17bf5..9a2173e8040 100644 --- a/tests/acceptance/expected-failures-with-oc10-server-oauth2-login.md +++ b/tests/acceptance/expected-failures-with-oc10-server-oauth2-login.md @@ -18,7 +18,7 @@ Other free text and markdown formatting can be used elsewhere in the document if - [webUISharingPublicManagement/shareByPublicLink.feature:24](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingPublicManagement/shareByPublicLink.feature#L24) ### [Uploading folders does not work in files-drop](https://github.com/owncloud/web/issues/2443) -- [webUISharingPublicDifferentRoles/shareByPublicLinkDifferentRoles.feature:268](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingPublicDifferentRoles/shareByPublicLinkDifferentRoles.feature#L268) +- [webUISharingPublicDifferentRoles/shareByPublicLinkDifferentRoles.feature:273](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingPublicDifferentRoles/shareByPublicLinkDifferentRoles.feature#L273) ### [Writing to locked files/folders give only a generic error message](https://github.com/owncloud/web/issues/5741) - [webUIWebdavLockProtection/upload.feature:32](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIWebdavLockProtection/upload.feature#L32) diff --git a/tests/acceptance/expected-failures-with-ocis-server-ocis-storage.md b/tests/acceptance/expected-failures-with-ocis-server-ocis-storage.md index 0ac96f7be7f..168a8046bb1 100644 --- a/tests/acceptance/expected-failures-with-ocis-server-ocis-storage.md +++ b/tests/acceptance/expected-failures-with-ocis-server-ocis-storage.md @@ -32,7 +32,7 @@ Other free text and markdown formatting can be used elsewhere in the document if - [webUIResharing1/reshareUsers.feature:177](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIResharing1/reshareUsers.feature#L177) ### [when sharer renames the shared resource, sharee get the updated name](https://github.com/owncloud/ocis/issues/2256) -- [webUIRenameFiles/renameFiles.feature:226](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIRenameFiles/renameFiles.feature#L226) +- [webUIRenameFiles/renameFiles.feature:227](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIRenameFiles/renameFiles.feature#L227) ### [Cannot create users with special characters](https://github.com/owncloud/ocis/issues/1417) - [webUISharingAutocompletion/shareAutocompletionSpecialChars.feature:37](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingAutocompletion/shareAutocompletionSpecialChars.feature#L37) @@ -54,7 +54,7 @@ Other free text and markdown formatting can be used elsewhere in the document if - [webUISharingExpirationDate/shareWithExpirationDate.feature:21](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingExpirationDate/shareWithExpirationDate.feature#L21) ### [Listing shares via ocs API does not show path for parent folders](https://github.com/owncloud/ocis/issues/1231) -- [webUISharingPublicManagement/shareByPublicLink.feature:110](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingPublicManagement/shareByPublicLink.feature#L110) +- [webUISharingPublicManagement/shareByPublicLink.feature:111](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingPublicManagement/shareByPublicLink.feature#L111) ### [Propfind response to trashbin endpoint is different in ocis](https://github.com/owncloud/product/issues/186) - [webUIFilesSearch/search.feature:131](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFilesSearch/search.feature#L131) @@ -82,13 +82,13 @@ Other free text and markdown formatting can be used elsewhere in the document if - [webUISharingPublicManagement/shareByPublicLink.feature:24](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingPublicManagement/shareByPublicLink.feature#L24) ### [Uploading folders does not work in files-drop](https://github.com/owncloud/web/issues/2443) -- [webUISharingPublicDifferentRoles/shareByPublicLinkDifferentRoles.feature:268](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingPublicDifferentRoles/shareByPublicLinkDifferentRoles.feature#L268) +- [webUISharingPublicDifferentRoles/shareByPublicLinkDifferentRoles.feature:273](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingPublicDifferentRoles/shareByPublicLinkDifferentRoles.feature#L273) ### [Resources cannot be locked under ocis](https://github.com/owncloud/ocis/issues/1284) -- [webUIWebdavLockProtection/delete.feature:33](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIWebdavLockProtection/delete.feature#L33) - [webUIWebdavLockProtection/delete.feature:34](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIWebdavLockProtection/delete.feature#L34) -- [webUIWebdavLockProtection/move.feature:36](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIWebdavLockProtection/move.feature#L36) +- [webUIWebdavLockProtection/delete.feature:35](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIWebdavLockProtection/delete.feature#L35) - [webUIWebdavLockProtection/move.feature:37](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIWebdavLockProtection/move.feature#L37) +- [webUIWebdavLockProtection/move.feature:38](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIWebdavLockProtection/move.feature#L38) - [webUIWebdavLockProtection/upload.feature:32](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIWebdavLockProtection/upload.feature#L32) ### [Resources cannot be locked under ocis](https://github.com/owncloud/ocis/issues/1284) @@ -111,7 +111,7 @@ Other free text and markdown formatting can be used elsewhere in the document if ### [Favorites deactivated in ocis temporarily](https://github.com/owncloud/ocis/issues/1228) - [webUIFilesDetails/fileDetails.feature:47](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFilesDetails/fileDetails.feature#L47) - [webUIFilesDetails/fileDetails.feature:67](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFilesDetails/fileDetails.feature#L67) -- [webUIRenameFiles/renameFiles.feature:249](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIRenameFiles/renameFiles.feature#L249) +- [webUIRenameFiles/renameFiles.feature:250](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIRenameFiles/renameFiles.feature#L250) ### [PROPFIND to sub-folder of a shared resources with same name gives 404](https://github.com/owncloud/ocis/issues/3859) - [webUISharingAcceptShares/acceptShares.feature:240](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingAcceptShares/acceptShares.feature#L240) diff --git a/tests/acceptance/features/webUIPrivateLinks/accessingPrivateLinks.feature b/tests/acceptance/features/webUIPrivateLinks/accessingPrivateLinks.feature index 074b940c826..683bd4847a6 100644 --- a/tests/acceptance/features/webUIPrivateLinks/accessingPrivateLinks.feature +++ b/tests/acceptance/features/webUIPrivateLinks/accessingPrivateLinks.feature @@ -11,6 +11,7 @@ Feature: Access private link Given user "Alice" has logged in using the webUI When the user copies the private link of the file "lorem.txt" using the webUI And the user navigates to the copied private link using the webUI + And the user closes the text editor using the webUI Then file "lorem.txt" should be listed on the webUI @smokeTest @@ -18,6 +19,7 @@ Feature: Access private link When an anonymous user tries to navigate to the private link created by user "Alice" for file "lorem.txt" Then the user should be redirected to the IdP login page When user "Alice" fills in the login form using the webUI + And the user closes the text editor using the webUI Then file "lorem.txt" should be listed on the webUI @@ -27,6 +29,7 @@ Feature: Access private link And user "Brian" has logged in using the webUI When the user navigates to the private link created by user "Alice" for file "lorem.txt" And the private link resolved successfully + And the user closes the text editor using the webUI Then file "lorem.txt" should be listed on the webUI @issue-3243 diff --git a/tests/acceptance/features/webUIRenameFiles/renameFiles.feature b/tests/acceptance/features/webUIRenameFiles/renameFiles.feature index d5a5da9cdd1..bdc8d8149ce 100644 --- a/tests/acceptance/features/webUIRenameFiles/renameFiles.feature +++ b/tests/acceptance/features/webUIRenameFiles/renameFiles.feature @@ -188,6 +188,7 @@ Feature: rename files And user "Alice" has uploaded file "lorem.txt" to "simple-folder/lorem.txt" in the server And user "Alice" has shared folder "simple-folder" with link with "read, update, create, delete" permissions in the server When the public uses the webUI to access the last public link created by user "Alice" in a new session + And the user closes the text editor using the webUI And the user renames single share "lorem.txt" to "a-renamed-file.txt" using the webUI Then file "a-renamed-file.txt" should be listed on the webUI as single share But file "lorem.txt" should not be listed on the webUI diff --git a/tests/acceptance/features/webUISharingPublicBasic/publicLinkCreate.feature b/tests/acceptance/features/webUISharingPublicBasic/publicLinkCreate.feature index 86365ce1e0a..a0366592b73 100644 --- a/tests/acceptance/features/webUISharingPublicBasic/publicLinkCreate.feature +++ b/tests/acceptance/features/webUISharingPublicBasic/publicLinkCreate.feature @@ -22,6 +22,7 @@ Feature: Create public link shares | name | Link | And a link named "Link" should be listed with role "Anyone with the link can view" in the public link list of resource "simple-folder" on the webUI When the public uses the webUI to access the last public link created by user "Alice" in a new session + And the user closes the text editor using the webUI Then file "lorem.txt" should be listed on the webUI as single share @smokeTest @ocisSmokeTest @issue-ocis-reva-383 @@ -38,6 +39,7 @@ Feature: Create public link shares | name | Link | And a link named "Link" should be listed with role "Anyone with the link can view" in the public link list of resource "lorem.txt" on the webUI When the public uses the webUI to access the last public link created by user "Alice" in a new session + And the user closes the text editor using the webUI Then file "lorem.txt" should be listed on the webUI as single share @skipOnOC10 @issue-ocis-reva-383 @@ -54,6 +56,7 @@ Feature: Create public link shares | permissions | read | | path | /simple-folder | When the public uses the webUI to access the last public link created by user "Alice" in a new session + And the user closes the text editor using the webUI Then file "lorem.txt" should be listed on the webUI as single share @skipOnOC10 @issue-ocis-reva-383 @@ -69,6 +72,7 @@ Feature: Create public link shares | permissions | read | | path | /lorem.txt | When the public uses the webUI to access the last public link created by user "Alice" in a new session + And the user closes the text editor using the webUI Then file "lorem.txt" should be listed on the webUI as single share @issue-ocis-reva-389 @@ -79,6 +83,7 @@ Feature: Create public link shares And user "Alice" has logged in using the webUI When the user creates a new public link for folder "aquickbrownfoxjumpsoveraverylazydogaquickbrownfoxjumpsoveralazydog" using the webUI And the public uses the webUI to access the last public link created by user "Alice" in a new session + And the user closes the text editor using the webUI Then file "lorem.txt" should be listed on the webUI as single share diff --git a/tests/acceptance/features/webUISharingPublicBasic/publicLinkEdit.feature b/tests/acceptance/features/webUISharingPublicBasic/publicLinkEdit.feature index 522b0a8885e..0f155dbf0d8 100644 --- a/tests/acceptance/features/webUISharingPublicBasic/publicLinkEdit.feature +++ b/tests/acceptance/features/webUISharingPublicBasic/publicLinkEdit.feature @@ -69,6 +69,7 @@ Feature: Edit public link shares | password | pass123 | When the user renames the public link named "Public-link" of folder "simple-folder" to "simple-folder Share" And the public uses the webUI to access the last public link created by user "Alice" with password "pass123" in a new session + And the user closes the text editor using the webUI Then file "lorem.txt" should be listed on the webUI as single share @@ -83,6 +84,7 @@ Feature: Edit public link shares And user "Alice" has logged in using the webUI When the user tries to edit the public link named "Public-link" of folder "simple-folder" changing the password to "qwertyui" And the public uses the webUI to access the last public link created by user "Alice" with password "qwertyui" in a new session + And the user closes the text editor using the webUI Then file "lorem.txt" should be listed on the webUI as single share @issue-3830 @@ -110,6 +112,7 @@ Feature: Edit public link shares And user "Alice" has logged in using the webUI When the user tries to edit the public link named "Public-link" of folder "simple-folder" changing the role to "Viewer" And the public uses the webUI to access the last public link created by user "Alice" in a new session + And the user closes the text editor using the webUI Then file "lorem.txt" should be listed on the webUI as single share And it should not be possible to delete file "lorem.txt" as single share using the webUI @@ -156,6 +159,7 @@ Feature: Edit public link shares And user "Alice" has logged in using the webUI When the user tries to edit the public link named "Public-link" of folder "simple-folder" changing the role to "Contributor" And the public uses the webUI to access the last public link created by user "Alice" in a new session + And the user closes the text editor using the webUI And the user uploads file "lorem.txt" using the webUI Then file "simple.txt" should be listed on the webUI And file "lorem.txt" should be listed on the webUI @@ -169,4 +173,5 @@ Feature: Edit public link shares And user "Alice" has logged in using the webUI When the user tries to edit the public link named "Public-link" of folder "lorem.txt" adding a password "pass123" And the public uses the webUI to access the last public link created by user "Alice" with password "pass123" in a new session + And the user closes the text editor using the webUI Then file "lorem.txt" should be listed on the webUI as single share diff --git a/tests/acceptance/features/webUISharingPublicBasic/publicLinkPublicActions.feature b/tests/acceptance/features/webUISharingPublicBasic/publicLinkPublicActions.feature index d15ff6bbc7a..6685759051b 100644 --- a/tests/acceptance/features/webUISharingPublicBasic/publicLinkPublicActions.feature +++ b/tests/acceptance/features/webUISharingPublicBasic/publicLinkPublicActions.feature @@ -13,6 +13,7 @@ Feature: Access public link shares by public Given user "Alice" has created file "simple-folder/lorem.txt" in the server And user "Alice" has shared folder "simple-folder" with link with "read, update, create, delete" permissions and password "pass123" in the server When the public uses the webUI to access the last public link created by user "Alice" with password "pass123" in a new session + And the user closes the text editor using the webUI Then file "lorem.txt" should be listed on the webUI as single share diff --git a/tests/acceptance/features/webUISharingPublicDifferentRoles/shareByPublicLinkDifferentRoles.feature b/tests/acceptance/features/webUISharingPublicDifferentRoles/shareByPublicLinkDifferentRoles.feature index a7dd3745ff2..1a9f4aa60c1 100644 --- a/tests/acceptance/features/webUISharingPublicDifferentRoles/shareByPublicLinkDifferentRoles.feature +++ b/tests/acceptance/features/webUISharingPublicDifferentRoles/shareByPublicLinkDifferentRoles.feature @@ -27,6 +27,7 @@ Feature: Share by public link with different roles # | name | Link | # And a link named "Link" should be listed with role "" in the public link list of folder "simple-folder" on the webUI When the public uses the webUI to access the last public link created by user "Alice" in a new session + And the user closes the text editor using the webUI Then file "lorem.txt" should be listed on the webUI as single share Examples: | role | permissions | @@ -47,6 +48,7 @@ Feature: Share by public link with different roles | name | Link | And a link named "Link" should be listed with role "" in the public link list of folder "simple-folder" on the webUI When the public uses the webUI to access the last public link created by user "Alice" in a new session + And the user closes the text editor using the webUI Then file "lorem.txt" should be listed on the webUI as single share Examples: | role | displayed-role | permissions | @@ -68,6 +70,7 @@ Feature: Share by public link with different roles | permissions | | | path | /simple-folder | When the public uses the webUI to access the last public link created by user "Alice" in a new session + And the user closes the text editor using the webUI Then file "lorem.txt" should be listed on the webUI as single share Examples: | role | permissions | @@ -156,6 +159,7 @@ Feature: Share by public link with different roles Given user "Alice" has created file "simple-folder/lorem.txt" in the server And user "Alice" has shared folder "simple-folder" with link with "read" permissions in the server When the public uses the webUI to access the last public link created by user "Alice" in a new session + And the user closes the text editor using the webUI Then it should not be possible to delete file "lorem.txt" as single share using the webUI @@ -163,6 +167,7 @@ Feature: Share by public link with different roles Given user "Alice" has shared folder "simple-folder" with link with "read, update, create, delete" permissions in the server When the public uses the webUI to access the last public link created by user "Alice" in a new session And the user uploads file "new-lorem.txt" using the webUI + And the user closes the text editor using the webUI Then file "new-lorem.txt" should be listed on the webUI as single share And as "Alice" file "simple-folder/new-lorem.txt" should exist in the server @@ -203,10 +208,10 @@ Feature: Share by public link with different roles Given user "Alice" has shared folder "simple-folder" with link with "read, update, create, delete" permissions and password "pass123" in the server When the public uses the webUI to access the last public link created by user "Alice" with password "pass123" in a new session And the user uploads file "new-lorem.txt" using the webUI + And the user closes the text editor using the webUI Then file "new-lorem.txt" should be listed on the webUI as single share And as "Alice" file "simple-folder/new-lorem.txt" should exist in the server - Scenario: creating a public link with "Editor" role makes it possible to upload files inside a subdirectory Given user "Alice" has created folder "simple-folder/simple-empty-folder" in the server And user "Alice" has shared folder "simple-folder" with link with "read, update, create, delete" permissions in the server diff --git a/tests/acceptance/features/webUISharingPublicManagement/shareByPublicLink.feature b/tests/acceptance/features/webUISharingPublicManagement/shareByPublicLink.feature index 89f88a40769..79bc288b63d 100644 --- a/tests/acceptance/features/webUISharingPublicManagement/shareByPublicLink.feature +++ b/tests/acceptance/features/webUISharingPublicManagement/shareByPublicLink.feature @@ -77,6 +77,7 @@ Feature: Public link share management And user "Alice" has logged in using the webUI When the user copies the url of public link named "Public-link" of folder "simple-folder" using the webUI And the user navigates to the copied public link using the webUI + And the user closes the text editor using the webUI Then file "lorem.txt" should be listed on the webUI as single share @@ -131,6 +132,7 @@ Feature: Public link share management | name | public link | | permissions | read | When the public uses the webUI to access the last public link created by user "Alice" in a new session + And the user closes the text editor using the webUI Then file "lorem.txt" should be listed on the webUI as single share And the create button should not be visible on the webUI diff --git a/tests/acceptance/features/webUISharingPublicManagement/sharingPublicSession.feature b/tests/acceptance/features/webUISharingPublicManagement/sharingPublicSession.feature index 4f1669c7b72..255cdcfcb72 100644 --- a/tests/acceptance/features/webUISharingPublicManagement/sharingPublicSession.feature +++ b/tests/acceptance/features/webUISharingPublicManagement/sharingPublicSession.feature @@ -12,6 +12,7 @@ Feature: Session storage for public link And user "Alice" has created file "simple-folder/lorem.txt" in the server And user "Alice" has shared folder "simple-folder" with link with "read" permissions and password "pass123" in the server When the public uses the webUI to access the last public link created by user "Alice" with password "pass123" in a new session + And the user closes the text editor using the webUI Then file "lorem.txt" should be listed on the webUI as single share When the user reloads the current page of the webUI Then file "lorem.txt" should be listed on the webUI as single share @@ -22,6 +23,7 @@ Feature: Session storage for public link And user "Alice" has created file "simple-folder/lorem.txt" in the server And user "Alice" has shared folder "simple-folder" with link with "read" permissions and password "pass123" in the server When the public uses the webUI to access the last public link created by user "Alice" with password "pass123" in a new session + And the user closes the text editor using the webUI Then file "lorem.txt" should be listed on the webUI as single share @@ -29,6 +31,7 @@ Feature: Session storage for public link Given user "Alice" has created file "lorem.txt" in the server And user "Alice" has shared folder "lorem.txt" with link with "read" permissions and password "pass123" in the server When the public uses the webUI to access the last public link created by user "Alice" with password "pass123" in a new session + And the user closes the text editor using the webUI Then file "lorem.txt" should be listed on the webUI as single share @@ -37,6 +40,7 @@ Feature: Session storage for public link And user "Alice" has created file "simple-folder/lorem.txt" in the server And user "Alice" has shared folder "simple-folder" with link with "read" permissions and password "pass123" in the server When the public uses the webUI to access the last public link created by user "Alice" with password "pass123" in a new session + And the user closes the text editor using the webUI Then file "lorem.txt" should be listed on the webUI as single share And user "Alice" changes the password of last public link to "newpass" using the Sharing API in the server When the user reloads the current page of the webUI @@ -49,6 +53,7 @@ Feature: Session storage for public link Given user "Alice" has created file "lorem.txt" in the server And user "Alice" has shared folder "lorem.txt" with link with "read" permissions and password "pass123" in the server When the public uses the webUI to access the last public link created by user "Alice" with password "pass123" in a new session + And the user closes the text editor using the webUI Then file "lorem.txt" should be listed on the webUI as single share And user "Alice" changes the password of last public link to "newpass" using the Sharing API in the server When the user reloads the current page of the webUI diff --git a/tests/acceptance/features/webUIUpload/upload.feature b/tests/acceptance/features/webUIUpload/upload.feature index 9eb76b3816e..956b687644f 100644 --- a/tests/acceptance/features/webUIUpload/upload.feature +++ b/tests/acceptance/features/webUIUpload/upload.feature @@ -137,11 +137,11 @@ Feature: File Upload Scenario: upload overwriting a file into a public share Given user "Alice" has shared folder "simple-folder" with link with "read, update, create, delete" permissions and password "pass123" in the server When the public uses the webUI to access the last public link created by user "Alice" with password "pass123" in a new session + And the user closes the text editor using the webUI And the user uploads overwriting file "lorem.txt" using the webUI Then file "lorem.txt" should be listed on the webUI as single share And as "Alice" the content of "simple-folder/lorem.txt" in the server should be the same as the content of local file "lorem.txt" - Scenario: upload a file with comma in the filename When the user uploads file "file,with,comma,.txt" using the webUI Then no message should be displayed on the webUI diff --git a/tests/acceptance/features/webUIWebdavLockProtection/delete.feature b/tests/acceptance/features/webUIWebdavLockProtection/delete.feature index 5fdf4501415..c72a30a0fab 100644 --- a/tests/acceptance/features/webUIWebdavLockProtection/delete.feature +++ b/tests/acceptance/features/webUIWebdavLockProtection/delete.feature @@ -21,6 +21,7 @@ Feature: Locks | path | simple-folder | | permissions | read, create, delete, update | When the public uses the webUI to access the last public link created by user "brand-new-user" in a new session + And the user closes the text editor using the webUI And the user tries to delete single share "lorem.txt" using the webUI Then notifications should be displayed on the webUI with the text """ diff --git a/tests/acceptance/features/webUIWebdavLockProtection/move.feature b/tests/acceptance/features/webUIWebdavLockProtection/move.feature index fe37e839226..bec5b6ce9d6 100644 --- a/tests/acceptance/features/webUIWebdavLockProtection/move.feature +++ b/tests/acceptance/features/webUIWebdavLockProtection/move.feature @@ -22,6 +22,7 @@ Feature: Locks | path | simple-folder | | permissions | read, create, delete, update | When the public uses the webUI to access the last public link created by user "brand-new-user" in a new session + And the user closes the text editor using the webUI And the user tries to rename single share "lorem.txt" to "a-renamed-file.txt" using the webUI Then notifications should be displayed on the webUI with the text """ diff --git a/tests/acceptance/pageObjects/webPage.js b/tests/acceptance/pageObjects/webPage.js index 40a83778d7e..e81cee91714 100644 --- a/tests/acceptance/pageObjects/webPage.js +++ b/tests/acceptance/pageObjects/webPage.js @@ -279,7 +279,7 @@ module.exports = { selector: '#web' }, appContainer: { - selector: '#files-view' + selector: '.app-container' }, notificationElement: { selector: '//div[@id="oc-notifications"]//div[contains(@class, "oc-notifications-message")]', diff --git a/tests/e2e/cucumber/features/smoke/link.feature b/tests/e2e/cucumber/features/smoke/link.feature index 9c2057fe1d4..8b7080bd2fa 100644 --- a/tests/e2e/cucumber/features/smoke/link.feature +++ b/tests/e2e/cucumber/features/smoke/link.feature @@ -60,6 +60,7 @@ Feature: link And "Alice" opens the "files" app When "Alice" copies quick link of the resource "folderPublic" from the context menu And "Anonymous" opens the public link "Link" + And "Anonymous" closes the editor And "Anonymous" downloads the following public link resources using the single share view | resource | type | | lorem.txt | file | diff --git a/tests/e2e/cucumber/features/smoke/spaces/participantManagement.ocis.feature b/tests/e2e/cucumber/features/smoke/spaces/participantManagement.ocis.feature index a6cdfde6b18..7abfa9778aa 100644 --- a/tests/e2e/cucumber/features/smoke/spaces/participantManagement.ocis.feature +++ b/tests/e2e/cucumber/features/smoke/spaces/participantManagement.ocis.feature @@ -65,6 +65,7 @@ Feature: spaces participant management And "Alice" creates a public link for the resource "parent" using the sidebar panel And "Alice" edits the public link named "Link" of resource "parent" changing role to "editor" And "Anonymous" opens the public link "Link" + And "Anonymous" closes the editor And "Anonymous" uploads the following resources in public link page | resource | | textfile.txt | diff --git a/tests/e2e/cucumber/steps/ui/public.ts b/tests/e2e/cucumber/steps/ui/public.ts index 33bab0771b6..030fb3a6547 100644 --- a/tests/e2e/cucumber/steps/ui/public.ts +++ b/tests/e2e/cucumber/steps/ui/public.ts @@ -3,6 +3,7 @@ import { Page } from 'playwright' import { World } from '../../environment' import { objects } from '../../../support' import { processDelete, processDownload } from './resources' +import { editor } from '../../../support/objects/app-files/utils' When( '{string} opens the public link {string}', @@ -34,6 +35,11 @@ When( } ) +When('{string} closes the editor', async function (this: World, stepUser: string): Promise { + const { page } = this.actorsEnvironment.getActor({ key: stepUser }) + await editor.close(page) +}) + When( '{string} drop uploads following resources', async function (this: World, stepUser: string, stepTable: DataTable): Promise { diff --git a/tests/e2e/support/objects/app-files/resource/actions.ts b/tests/e2e/support/objects/app-files/resource/actions.ts index d6b5905c874..56bc6a74281 100644 --- a/tests/e2e/support/objects/app-files/resource/actions.ts +++ b/tests/e2e/support/objects/app-files/resource/actions.ts @@ -3,7 +3,7 @@ import { expect } from '@playwright/test' import util from 'util' import path from 'path' import { resourceExists, waitForResources } from './utils' -import { sidebar } from '../utils' +import { sidebar, editor } from '../utils' import { File, Space } from '../../../types' import { dragDropFiles } from '../../../utils/dragDrop' import { config } from '../../../../config' @@ -30,7 +30,6 @@ const createNewTxtFileButton = '.new-file-btn-txt' const createNewMdFileButton = '.new-file-btn-md' const createNewDrawioFileButton = '.new-file-btn-drawio' const saveTextFileInEditorButton = '#text-editor-controls-save:visible' -const closeTextEditorOrViewerButton = '#app-top-bar-close' const textEditorInput = '#text-editor-input' const resourceNameInput = '.oc-modal input' const resourceUploadButton = '#upload-menu-btn' @@ -272,7 +271,7 @@ export const editTextDocument = async ({ page.waitForResponse((resp) => resp.status() === 207 && resp.request().method() === 'PROPFIND'), page.locator(saveTextFileInEditorButton).click() ]) - await Promise.all([page.waitForNavigation(), page.locator(closeTextEditorOrViewerButton).click()]) + await editor.close(page) await page.locator(util.format(resourceNameSelector, name)).waitFor() } @@ -1115,7 +1114,7 @@ export const openFileInViewer = async (args: openFileInViewerArgs): Promise => { + return Promise.all([ + page.waitForNavigation(), + page.locator(closeTextEditorOrViewerButton).click() + ]) +} diff --git a/tests/e2e/support/objects/app-files/utils/index.ts b/tests/e2e/support/objects/app-files/utils/index.ts index 2d69a19c2cd..4ebb14d7cc5 100644 --- a/tests/e2e/support/objects/app-files/utils/index.ts +++ b/tests/e2e/support/objects/app-files/utils/index.ts @@ -1 +1,2 @@ export * as sidebar from './sidebar' +export * as editor from './editor'