diff --git a/__fixtures__/sharedViaLinkFiles.js b/__fixtures__/sharedViaLinkFiles.js
index 86dbe952a61..d6a4e1d536e 100644
--- a/__fixtures__/sharedViaLinkFiles.js
+++ b/__fixtures__/sharedViaLinkFiles.js
@@ -20,8 +20,8 @@ const files = {
storage_id: 'home::admin',
storage: 2,
item_type: 'folder',
- item_source: 3009,
- file_source: 3009,
+ item_source: 3007,
+ file_source: 3007,
file_parent: 6,
file_target: '/Documents',
name: 'Quick action link',
@@ -55,8 +55,8 @@ const files = {
storage_id: 'home::admin',
storage: 2,
item_type: 'folder',
- item_source: 3009,
- file_source: 3009,
+ item_source: 3008,
+ file_source: 3008,
file_parent: 6,
file_target: '/.hidden-folder',
name: 'Quick action link',
diff --git a/changelog/unreleased/enhancement-update-ods b/changelog/unreleased/enhancement-update-ods
new file mode 100644
index 00000000000..e82c37fc29c
--- /dev/null
+++ b/changelog/unreleased/enhancement-update-ods
@@ -0,0 +1,12 @@
+Enhancement: Update ODS to 9.3.0
+
+We updated the ownCloud Design System to version 9.3.0. Please refer to the full changelog in the ODS release (linked) for more details. Summary:
+- Bugfix - Fix search for options provided as objects: https://github.com/owncloud/owncloud-design-system/pull/1602
+- Bugfix - Contextmenu button triggered wrong event: https://github.com/owncloud/owncloud-design-system/pull/1610
+- Bugfix - Use pointer cursor for OcSelect actions: https://github.com/owncloud/owncloud-design-system/pull/1604
+- Enhancement - OcTableFiles Contextmenu Tooltip: https://github.com/owncloud/owncloud-design-system/pull/1610
+- Enhancement - Highlight droptarget in OcTableFiles: https://github.com/owncloud/owncloud-design-system/pull/1610
+- Enhancement - Remove "Showdetails" button in OcTableFiles: https://github.com/owncloud/owncloud-design-system/pull/1610
+
+https://github.com/owncloud/web/pull/5725
+https://github.com/owncloud/owncloud-design-system/releases/tag/v9.3.0
diff --git a/dev/docker/oc10.web.config.json b/dev/docker/oc10.web.config.json
index f2782dc632a..fbe3a0b3bf3 100644
--- a/dev/docker/oc10.web.config.json
+++ b/dev/docker/oc10.web.config.json
@@ -1,16 +1,12 @@
{
- "server" : "http://host.docker.internal:8080",
+ "server": "http://host.docker.internal:8080",
"auth": {
"clientId": "M8W5mo3wQV3VHWYsaYpWhkr8dwa949i4GljCkedHhl7GWqmHMkxSeJgK2PcS0jt5",
"url": "http://host.docker.internal:8080/index.php/apps/oauth2/api/v1/token",
"authUrl": "http://host.docker.internal:8080/index.php/apps/oauth2/authorize"
},
- "apps": [
- "files",
- "media-viewer",
- "search"
- ],
- "applications" : [
+ "apps": ["files", "media-viewer", "markdown-editor", "search"],
+ "applications": [
{
"title": {
"en": "Classic Design",
@@ -32,4 +28,4 @@
"url": "http://host.docker.internal:8080/index.php/settings/personal"
}
]
-}
\ No newline at end of file
+}
diff --git a/dev/docker/ocis.web.config.json b/dev/docker/ocis.web.config.json
index 61d2e261b6c..4f070366228 100644
--- a/dev/docker/ocis.web.config.json
+++ b/dev/docker/ocis.web.config.json
@@ -1,39 +1,35 @@
{
- "server": "https://host.docker.internal:9200",
- "theme": "https://host.docker.internal:9200/themes/owncloud/theme.json",
- "version": "0.1.0",
- "openIdConnect": {
- "metadata_url": "https://host.docker.internal:9200/.well-known/openid-configuration",
- "authority": "https://host.docker.internal:9200",
- "client_id": "web",
- "response_type": "code",
- "scope": "openid profile email"
+ "server": "https://host.docker.internal:9200",
+ "theme": "https://host.docker.internal:9200/themes/owncloud/theme.json",
+ "version": "0.1.0",
+ "openIdConnect": {
+ "metadata_url": "https://host.docker.internal:9200/.well-known/openid-configuration",
+ "authority": "https://host.docker.internal:9200",
+ "client_id": "web",
+ "response_type": "code",
+ "scope": "openid profile email"
+ },
+ "options": {
+ "hideSearchBar": true
+ },
+ "apps": ["files", "media-viewer", "markdown-editor", "search"],
+ "external_apps": [
+ {
+ "id": "settings",
+ "path": "https://host.docker.internal:9200/settings.js"
},
- "options": {
- "hideSearchBar": true
+ {
+ "id": "accounts",
+ "path": "https://host.docker.internal:9200/accounts.js"
},
- "apps": [
- "files",
- "media-viewer",
- "search"
- ],
- "external_apps": [
- {
- "id": "settings",
- "path": "https://host.docker.internal:9200/settings.js"
- },
- {
- "id": "accounts",
- "path": "https://host.docker.internal:9200/accounts.js"
- },
- {
- "id": "draw-io",
- "path": "web-app-draw-io",
- "config": {
- "url": "https://embed.diagrams.net",
- "autosave": false,
- "theme": "minimal"
- }
- }
- ]
-}
\ No newline at end of file
+ {
+ "id": "draw-io",
+ "path": "web-app-draw-io",
+ "config": {
+ "url": "https://embed.diagrams.net",
+ "autosave": false,
+ "theme": "minimal"
+ }
+ }
+ ]
+}
diff --git a/packages/web-app-files/src/components/AppBar/ViewOptions.vue b/packages/web-app-files/src/components/AppBar/ViewOptions.vue
index 1f459c9cd97..c73518597e3 100644
--- a/packages/web-app-files/src/components/AppBar/ViewOptions.vue
+++ b/packages/web-app-files/src/components/AppBar/ViewOptions.vue
@@ -14,6 +14,7 @@
- {{ highlightedFile.name }}
+
diff --git a/packages/web-app-files/src/helpers/resources.js b/packages/web-app-files/src/helpers/resources.js
index 7506dc08c1e..070b28bfc02 100644
--- a/packages/web-app-files/src/helpers/resources.js
+++ b/packages/web-app-files/src/helpers/resources.js
@@ -117,7 +117,7 @@ export function aggregateResourceShares(
const resources = []
let prev = null
for (const share of shares) {
- if (prev && share.path === prev.path) {
+ if (prev?.storage_id === share.storage_id && prev?.file_source === share.file_source) {
if (userShareTypes.includes(share.share_type)) {
prev.sharedWith.push({
username: share.share_with,
diff --git a/packages/web-app-files/src/mixins/actions/showActions.js b/packages/web-app-files/src/mixins/actions/showActions.js
index 1143ee23bde..6f38ae13a87 100644
--- a/packages/web-app-files/src/mixins/actions/showActions.js
+++ b/packages/web-app-files/src/mixins/actions/showActions.js
@@ -1,4 +1,4 @@
-import { mapMutations } from 'vuex'
+import { mapActions, mapMutations } from 'vuex'
import { isTrashbinRoute } from '../../helpers/route'
export default {
@@ -18,8 +18,10 @@ export default {
},
methods: {
...mapMutations('Files', ['SET_APP_SIDEBAR_ACTIVE_PANEL']),
+ ...mapActions('Files/sidebar', { openSidebar: 'open' }),
- $_showActions_trigger() {
+ async $_showActions_trigger() {
+ await this.openSidebar()
this.SET_APP_SIDEBAR_ACTIVE_PANEL(isTrashbinRoute(this.$route) ? null : 'actions-item')
}
}
diff --git a/packages/web-app-files/src/mixins/actions/showDetails.js b/packages/web-app-files/src/mixins/actions/showDetails.js
index 095e078af64..dea62371487 100644
--- a/packages/web-app-files/src/mixins/actions/showDetails.js
+++ b/packages/web-app-files/src/mixins/actions/showDetails.js
@@ -1,4 +1,4 @@
-import { mapMutations } from 'vuex'
+import { mapActions, mapMutations } from 'vuex'
import { isTrashbinRoute } from '../../helpers/route'
export default {
@@ -18,8 +18,10 @@ export default {
},
methods: {
...mapMutations('Files', ['SET_APP_SIDEBAR_ACTIVE_PANEL']),
+ ...mapActions('Files/sidebar', { openSidebar: 'open' }),
- $_showDetails_trigger() {
+ async $_showDetails_trigger() {
+ await this.openSidebar()
this.SET_APP_SIDEBAR_ACTIVE_PANEL(null)
}
}
diff --git a/packages/web-runtime/package.json b/packages/web-runtime/package.json
index 1112a08933f..07ad34770b9 100644
--- a/packages/web-runtime/package.json
+++ b/packages/web-runtime/package.json
@@ -13,7 +13,7 @@
"lodash-es": "^4.17.21",
"luxon": "^1.27.0",
"oidc-client": "1.11.5",
- "owncloud-design-system": "^9.2.0",
+ "owncloud-design-system": "^9.3.0",
"owncloud-sdk": "1.0.0-2296",
"p-queue": "^6.1.1",
"portal-vue": "^2.1.7",
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 e1267cb27e2..5524fd95c24 100644
--- a/tests/acceptance/expected-failures-with-oc10-server-oauth2-login.md
+++ b/tests/acceptance/expected-failures-with-oc10-server-oauth2-login.md
@@ -63,9 +63,6 @@ Other free text and markdown formatting can be used elsewhere in the document if
- [webUISharingNotifications/notificationLink.feature:18](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingNotifications/notificationLink.feature#L18)
- [webUISharingNotificationsToRoot/notificationLink.feature:17](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingNotificationsToRoot/notificationLink.feature#L17)
-### [Cannot determine share source path when sharing same name file from different path in shared-with pages](https://github.com/owncloud/web/issues/5302)
-- [webUISharingPublicBasic/publicLinkCreate.feature:88](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingPublicBasic/publicLinkCreate.feature#L88)
-
### [impossible to navigate into a folder in the trashbin](https://github.com/owncloud/web/issues/1725)
- [webUITrashbinDelete/trashbinDelete.feature:29](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUITrashbinDelete/trashbinDelete.feature#L29)
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 7b4c406c34a..c868e33a492 100644
--- a/tests/acceptance/expected-failures-with-ocis-server-ocis-storage.md
+++ b/tests/acceptance/expected-failures-with-ocis-server-ocis-storage.md
@@ -53,9 +53,6 @@ Other free text and markdown formatting can be used elsewhere in the document if
- [webUISharingInternalUsersShareWithPage/shareWithUsers.feature:118](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingInternalUsersShareWithPage/shareWithUsers.feature#L118)
- [webUIResharing1/reshareUsers.feature:230](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIResharing1/reshareUsers.feature#L230)
-### [delete pending share option is not available for sharee](https://github.com/owncloud/web/issues/5435)
-- [webUIDeleteFilesFolders/deleteFilesFolders.feature:235](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIDeleteFilesFolders/deleteFilesFolders.feature#L235)
-
### [file_path property is not unique for a share created with same resource name i.e already present in sharee](https://github.com/owncloud/ocis/issues/2249)
- [webUIRenameFiles/renameFiles.feature:205](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIRenameFiles/renameFiles.feature#L205)
@@ -207,8 +204,8 @@ Other free text and markdown formatting can be used elsewhere in the document if
- [webUIPrivateLinks/accessingPrivateLinks.feature:9](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIPrivateLinks/accessingPrivateLinks.feature#L9)
- [webUIPrivateLinks/accessingPrivateLinks.feature:17](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIPrivateLinks/accessingPrivateLinks.feature#L17)
- [webUIPrivateLinks/accessingPrivateLinks.feature:25](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIPrivateLinks/accessingPrivateLinks.feature#L25)
-- [webUIPrivateLinks/accessingPrivateLinks.feature:34](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIPrivateLinks/accessingPrivateLinks.feature#L34)
-- [webUIPrivateLinks/accessingPrivateLinks.feature:44](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIPrivateLinks/accessingPrivateLinks.feature#L44)
+- [webUIPrivateLinks/accessingPrivateLinks.feature:35](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIPrivateLinks/accessingPrivateLinks.feature#L34)
+- [webUIPrivateLinks/accessingPrivateLinks.feature:45](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIPrivateLinks/accessingPrivateLinks.feature#L44)
### [various sharing settings cannot be set](https://github.com/owncloud/ocis/issues/1328)
- [webUIRestrictSharing/disableSharing.feature:16](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIRestrictSharing/disableSharing.feature#L16)
@@ -429,9 +426,6 @@ Other free text and markdown formatting can be used elsewhere in the document if
- [webUISharingInternalGroupsEdgeCases/shareWithGroupsEdgeCases.feature:41](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingInternalGroupsEdgeCases/shareWithGroupsEdgeCases.feature#L41)
- [webUISharingInternalGroupsEdgeCases/shareWithGroupsEdgeCases.feature:42](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingInternalGroupsEdgeCases/shareWithGroupsEdgeCases.feature#L42)
-### [Cannot determine share source path when sharing same name file from different path in shared-with pages](https://github.com/owncloud/web/issues/5302)
-- [webUISharingPublicBasic/publicLinkCreate.feature:88](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingPublicBasic/publicLinkCreate.feature#L88)
-
### [impossible to navigate into a folder in the trashbin](https://github.com/owncloud/web/issues/1725)
- [webUITrashbinDelete/trashbinDelete.feature:29](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUITrashbinDelete/trashbinDelete.feature#L29)
@@ -546,3 +540,6 @@ Other free text and markdown formatting can be used elsewhere in the document if
### [not possible to overwrite a received shared file](https://github.com/owncloud/ocis/issues/2267)
- [webUISharingInternalGroups/shareWithGroups.feature:77](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingInternalGroups/shareWithGroups.feature#L77)
- [webUISharingInternalUsers/shareWithUsers.feature:57](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingInternalUsers/shareWithUsers.feature#L57)
+
+### [shares are not listed with full paths](https://github.com/owncloud/ocis/issues/2462)
+- [webUISharingPublicBasic/publicLinkCreate.feature:88](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingPublicBasic/publicLinkCreate.feature#L88)
diff --git a/tests/acceptance/features/webUIFilesActionMenu/fileFolderActionMenu.feature b/tests/acceptance/features/webUIFilesActionMenu/fileFolderActionMenu.feature
index 157c6aa5efe..d4e7af2f5db 100644
--- a/tests/acceptance/features/webUIFilesActionMenu/fileFolderActionMenu.feature
+++ b/tests/acceptance/features/webUIFilesActionMenu/fileFolderActionMenu.feature
@@ -14,7 +14,6 @@ Background: prepare user and files
Scenario: observe different actions menu options on selecting different file types or folder
Given user "Alice" has uploaded file with content "pdf file" to "lorem.pdf"
And the user has reloaded the current page of the webUI
- And the app-sidebar for file "lorem.txt" has been visible on the webUI
When the user opens the actions sidebar panel of folder "simple-folder" on the webUI
Then the app-sidebar for folder "simple-folder" should be visible on the webUI
And only the following items with default items should be visible in the actions menu on the webUI
diff --git a/tests/acceptance/features/webUIFilesDetails/fileDetails.feature b/tests/acceptance/features/webUIFilesDetails/fileDetails.feature
index f6d2d3d0a75..a8ea9027f37 100644
--- a/tests/acceptance/features/webUIFilesDetails/fileDetails.feature
+++ b/tests/acceptance/features/webUIFilesDetails/fileDetails.feature
@@ -14,7 +14,7 @@ Feature: User can open the details panel for any file or folder
Scenario: View different areas of the app-sidebar for a file in files page
Given user "Alice" has created file "lorem.txt"
And the user has browsed to the files page
- When the user picks the row of file "lorem.txt" on the webUI
+ When the user opens the sidebar for file "lorem.txt" on the webUI
Then the app-sidebar should be visible
And the thumbnail should be visible in the app-sidebar
And the "details" details panel should be visible
@@ -27,7 +27,7 @@ Feature: User can open the details panel for any file or folder
Scenario: View different areas of the app-sidebar for a folder in files page
Given user "Alice" has created folder "simple-folder"
And the user has browsed to the files page
- When the user picks the row of folder "simple-folder" on the webUI
+ When the user opens the sidebar for folder "simple-folder" on the webUI
Then the app-sidebar should be visible
And the thumbnail should be visible in the app-sidebar
And the "details" details panel should be visible
@@ -44,7 +44,7 @@ Feature: User can open the details panel for any file or folder
And the user has browsed to the files page
And user "Alice" has favorited element "lorem.txt"
And the user has browsed to the favorites page
- When the user picks the row of file "lorem.txt" on the webUI
+ When the user opens the sidebar for file "lorem.txt" on the webUI
Then the app-sidebar should be visible
And the thumbnail should be visible in the app-sidebar
And the "details" details panel should be visible
@@ -59,7 +59,7 @@ Feature: User can open the details panel for any file or folder
And the user has browsed to the files page
And user "Alice" has favorited element "simple-folder"
And the user has browsed to the favorites page
- When the user picks the row of folder "simple-folder" on the webUI
+ When the user opens the sidebar for folder "simple-folder" on the webUI
Then the app-sidebar should be visible
And the thumbnail should be visible in the app-sidebar
And the "details" details panel should be visible
@@ -77,7 +77,7 @@ Feature: User can open the details panel for any file or folder
And user "Alice" has created a public link with following settings
| path | simple-folder |
And the user has browsed to the shared-via-link page
- When the user opens the file action menu of folder "simple-folder" using the webUI
+ When the user opens the actions sidebar panel of file "simple-folder" on the webUI
Then the thumbnail should be visible in the app-sidebar
When the user switches to "people" panel in details panel using the webUI
Then the "people" details panel should be visible
@@ -93,7 +93,7 @@ Feature: User can open the details panel for any file or folder
And user "Alice" has shared folder "simple-folder" with user "Brian"
When the user browses to the shared-with-others page
Then folder "simple-folder" should be listed on the webUI
- When the user picks the row of folder "simple-folder" on the webUI
+ When the user opens the sidebar for folder "simple-folder" on the webUI
Then the app-sidebar should be visible
And the thumbnail should be visible in the app-sidebar
When the user switches to "people" panel in details panel using the webUI
@@ -110,7 +110,7 @@ Feature: User can open the details panel for any file or folder
And user "Alice" has created a new public link for resource "simple-folder"
When the user browses to the shared-with-others page
Then folder "simple-folder" should be listed on the webUI
- When the user picks the row of folder "simple-folder" on the webUI
+ When the user opens the sidebar for folder "simple-folder" on the webUI
Then the app-sidebar should be visible
And the thumbnail should be visible in the app-sidebar
When the user switches to "people" panel in details panel using the webUI
@@ -128,7 +128,7 @@ Feature: User can open the details panel for any file or folder
And the user re-logs in as "Brian" using the webUI
When the user browses to the shared-with-me page
Then folder "simple-folder" should be listed on the webUI
- When the user picks the row of folder "simple-folder" on the webUI
+ When the user opens the sidebar for folder "simple-folder" on the webUI
Then the app-sidebar should be visible
And the thumbnail should be visible in the app-sidebar
When the user switches to "people" panel in details panel using the webUI
@@ -156,7 +156,7 @@ Feature: User can open the details panel for any file or folder
When the user browses to the tags page
And the user searches for tag "simple" using the webUI
Then folder "simple-folder" should be listed on the webUI
- When the user opens the file action menu of folder "simple-folder" using the webUI
+ When the user opens the actions sidebar panel of file "simple-folder" on the webUI
Then the thumbnail should be visible in the app-sidebar
When the user switches to "people" panel in details panel using the webUI
Then the "people" details panel should be visible
@@ -171,7 +171,7 @@ Feature: User can open the details panel for any file or folder
Scenario: the sidebar is invisible after closing
Given user "Alice" has created file "lorem.txt"
And the user has browsed to the files page
- When the user picks the row of file "lorem.txt" on the webUI
+ When the user opens the sidebar for file "lorem.txt" on the webUI
Then the app-sidebar should be visible
When the user closes the app-sidebar using the webUI
Then the app-sidebar should be invisible
@@ -180,6 +180,5 @@ Feature: User can open the details panel for any file or folder
Scenario: the sidebar is invisible after opening the selected folder
Given user "Alice" has created file "simple-folder"
And the user has browsed to the files page
- Given the app-sidebar for file "simple-folder" has been visible on the webUI
When the user opens folder "simple-folder" using the webUI
Then the app-sidebar should be invisible
diff --git a/tests/acceptance/features/webUIPrivateLinks/accessingPrivateLinks.feature b/tests/acceptance/features/webUIPrivateLinks/accessingPrivateLinks.feature
index c76a5bcec21..68d0a373c89 100644
--- a/tests/acceptance/features/webUIPrivateLinks/accessingPrivateLinks.feature
+++ b/tests/acceptance/features/webUIPrivateLinks/accessingPrivateLinks.feature
@@ -15,7 +15,7 @@ Feature: Access private link
@smokeTest @ocisSmokeTest
Scenario: Access private link before authorisation
- When the user tries to navigate to the private link created by user "Alice" for file "lorem.txt"
+ 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" has logged in using the webUI
Then the app-sidebar for file "lorem.txt" should be visible on the webUI
@@ -27,6 +27,7 @@ Feature: Access private link
And user "Alice" has shared file "lorem.txt" with user "Brian" with "read" permissions
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
Then the app-sidebar for file "lorem.txt" should be visible on the webUI
And the "details" details panel should be visible
@@ -42,5 +43,5 @@ Feature: Access private link
"""
Scenario: Access the private link anonymously
- When the user tries to navigate to the private link created by user "Alice" for file "lorem.txt"
+ 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
diff --git a/tests/acceptance/features/webUISharingInternalGroupsSharingIndicator/shareWithGroups.feature b/tests/acceptance/features/webUISharingInternalGroupsSharingIndicator/shareWithGroups.feature
index 907c7759f42..8e83638e247 100644
--- a/tests/acceptance/features/webUISharingInternalGroupsSharingIndicator/shareWithGroups.feature
+++ b/tests/acceptance/features/webUISharingInternalGroupsSharingIndicator/shareWithGroups.feature
@@ -140,6 +140,7 @@ Feature: Sharing files and folders with internal groups
| grp3 |
| grp4 |
And user "Alice" has created folder "simple-folder"
+ And user "Alice" has created folder "simple-folder2"
And user "Alice" has created file "simple-folder/testimage.png"
When user "Alice" has logged in using the webUI
Then the following resources should not have share indicators on the webUI
diff --git a/tests/acceptance/features/webUISharingPublicBasic/publicLinkCreate.feature b/tests/acceptance/features/webUISharingPublicBasic/publicLinkCreate.feature
index 6fab6cf16d6..fd4e179628c 100644
--- a/tests/acceptance/features/webUISharingPublicBasic/publicLinkCreate.feature
+++ b/tests/acceptance/features/webUISharingPublicBasic/publicLinkCreate.feature
@@ -85,7 +85,7 @@ Feature: Create public link shares
Then file "lorem.txt" should be listed on the webUI
@issue-5302
- Scenario: share two file with same name but different paths by public link
+ Scenario: share two files with same name but different paths by public link
Given user "Alice" has created folder "simple-folder"
And user "Alice" has created file "simple-folder/lorem.txt"
And user "Alice" has created file "lorem.txt"
diff --git a/tests/acceptance/features/webUISharingPublicManagement/shareByPublicLink.feature b/tests/acceptance/features/webUISharingPublicManagement/shareByPublicLink.feature
index d29cb72b0fb..11d617764d7 100644
--- a/tests/acceptance/features/webUISharingPublicManagement/shareByPublicLink.feature
+++ b/tests/acceptance/features/webUISharingPublicManagement/shareByPublicLink.feature
@@ -93,7 +93,7 @@ Feature: Public link share management
When the user creates a new public link for folder "simple-folder" using the webUI with
| role | Editor |
And the public uses the webUI to access the last public link created by user "Alice"
- And the user picks the row of file "lorem.txt" on the webUI
+ And the user opens the sidebar for file "lorem.txt" on the webUI
Then the following panels should be visible in the details dialog on the webUI
| name |
| versions |
diff --git a/tests/acceptance/pageObjects/FilesPageElement/appSideBar.js b/tests/acceptance/pageObjects/FilesPageElement/appSideBar.js
index 232960b2000..08e9b04b109 100644
--- a/tests/acceptance/pageObjects/FilesPageElement/appSideBar.js
+++ b/tests/acceptance/pageObjects/FilesPageElement/appSideBar.js
@@ -1,29 +1,66 @@
/* eslint-disable no-unused-expressions */
-const util = require('util')
const _ = require('lodash')
const timeoutHelper = require('../../helpers/timeoutHelper')
+const xpathHelper = require('../../helpers/xpath')
+const util = require('util')
module.exports = {
commands: {
isThumbnailVisible: function() {
- return this.waitForElementVisible(
- this.api.page.personalPage().elements.sideBar
- ).waitForElementVisible(this.elements.fileInfoIcon)
+ return this.waitForElementVisible('@sidebar').waitForElementVisible('@fileInfoIcon')
},
- closeSidebar: function(timeout = null) {
- timeout = timeoutHelper.parseTimeout(timeout)
+ closeSidebarIfOpen: async function(timeout = 300) {
+ if (!(await this.isSideBarOpen(timeout))) {
+ return this.api.page.FilesPageElement.filesList()
+ }
+
try {
- this.click({
+ await this.click({
selector: '@sidebarCloseBtn',
- timeout: timeout
+ timeout: timeoutHelper.parseTimeout(timeout)
})
} catch (e) {
// do nothing
}
return this.api.page.FilesPageElement.filesList()
},
+ isSideBarOpen: async function(timeout = 500) {
+ const element = this.elements.sidebar
+ let isVisible = false
+ await this.isVisible(
+ {
+ locateStrategy: element.locateStrategy,
+ selector: element.selector,
+ timeout: timeoutHelper.parseTimeout(timeout)
+ },
+ result => {
+ isVisible = result.value === true
+ }
+ )
+ return isVisible
+ },
+ isSideBarOpenForResource: async function(resource, elementType = 'any', timeout = 500) {
+ if (!(await this.isSideBarOpen(timeout))) {
+ return false
+ }
+ const selector = this.getResourceInfoSelector(resource, elementType)
+ let resourceInfoVisible = false
+ await this.isVisible({ locateStrategy: 'xpath', selector, timeout }, result => {
+ resourceInfoVisible = result.status === 0
+ })
+ return resourceInfoVisible
+ },
+ getResourceInfoSelector: function(resource, elementType = 'any') {
+ const name = xpathHelper.buildXpathLiteral(resource)
+ const path = xpathHelper.buildXpathLiteral('/' + resource)
+ if (elementType === 'any') {
+ return util.format(this.elements.fileInfoResourceNameAnyType.selector, name, path)
+ }
+ const type = xpathHelper.buildXpathLiteral(elementType)
+ return util.format(this.elements.fileInfoResourceName.selector, name, path, type)
+ },
activatePanel: async function(item) {
- await this.waitForElementVisible(this.api.page.personalPage().elements.sideBar)
+ const panelName = item === 'people' ? 'collaborators' : item
const active = await this.isPanelActive(
item,
this.api.globals.waitForNegativeConditionTimeout
@@ -34,7 +71,7 @@ module.exports = {
await this.isVisible(
{ locateStrategy: backBtn.locateStrategy, selector: backBtn.selector, timeout: 200 },
result => {
- backBtnVisible = result.status === 0
+ backBtnVisible = result.value === true
}
)
if (backBtnVisible) {
@@ -43,30 +80,16 @@ module.exports = {
})
await this.waitForAnimationToFinish() // wait for sliding animation to the root panel
}
- this.useXpath()
- .click(this.getXpathOfPanelSelect(item))
+ const menuItemElement = this.elements[panelName + 'PanelMenuItem']
+ await this.click({
+ locateStrategy: menuItemElement.locateStrategy,
+ selector: menuItemElement.selector
+ })
.waitForAjaxCallsToStartAndFinish()
- .useCss()
- await this.waitForAnimationToFinish() // wait for sliding animation to the sub panel
+ .waitForAnimationToFinish() // wait for sliding animation to the sub panel
}
- const panelName = item === 'people' ? 'collaborators' : item
- const element = this.elements[panelName + 'Panel']
- const selector = element.selector
- return this.waitForElementPresent(selector)
- },
- /**
- * return the complete xpath of the link to the specified panel in the side-bar
- * @param item
- * @returns {string}
- */
- getXpathOfPanelSelect: function(item) {
- return (
- this.api.page.personalPage().elements.sideBar.selector +
- util.format(
- "//button[contains(translate(.,'ABCDEFGHJIKLMNOPQRSTUVWXYZ','abcdefghjiklmnopqrstuvwxyz'),'%s')]",
- item
- )
- )
+ const panelElement = this.elements[panelName + 'Panel']
+ return await this.waitForElementPresent(panelElement.locateStrategy, panelElement.selector)
},
getVisibleAccordionItems: async function() {
const items = []
@@ -81,19 +104,6 @@ module.exports = {
}
return items
},
- getVisibleActionsMenuItems: async function() {
- const items = []
- let elements
- await this.api.elements('@panelActionsItems', function(result) {
- elements = result.value
- })
- for (const { ELEMENT } of elements) {
- await this.api.elementIdText(ELEMENT, function(result) {
- items.push(result.value.toLowerCase())
- })
- }
- return items
- },
getActionsMenuItemsExceptDefaults: async function() {
const defaultItems = ['add to favorites', 'copy', 'move', 'rename', 'delete']
const items = []
@@ -118,57 +128,66 @@ module.exports = {
isPanelActive: async function(panelName, timeout = null) {
panelName = panelName === 'people' ? 'collaborators' : panelName
const element = this.elements[panelName + 'Panel']
- const selector = element.selector + '.is-active'
let isVisible = false
- timeout = timeoutHelper.parseTimeout(timeout)
- await this.isVisible({ locateStrategy: 'css selector', selector, timeout }, result => {
- isVisible = result.value === true
- })
+ await this.isVisible(
+ {
+ locateStrategy: element.locateStrategy,
+ selector: element.selector,
+ timeout: timeoutHelper.parseTimeout(timeout)
+ },
+ result => {
+ isVisible = result.value === true
+ }
+ )
return isVisible
},
/**
- * checks if the item with the given selector is present on the files-page-sidebar
+ * checks if it's possible to navigate into the given panel
*
- * @param {object} selector
+ * @param {string} panelName
+ * @param {number} timeout
* @returns {Promise}
*/
- isPanelItemPresent: async function(selector) {
- let isPresent = true
- await this.useXpath()
- .waitForElementVisible(this.api.page.personalPage().elements.sideBar) // sidebar is expected to be opened and visible
- .api.elements(selector, result => {
- isPresent = result.value.length > 0
- })
- .useCss()
- return isPresent
+ isPanelSelectable: async function(panelName, timeout = 300) {
+ panelName = panelName === 'people' ? 'collaborators' : panelName
+ const element = this.elements[panelName + 'PanelMenuItem']
+ let isVisible = false
+ await this.isVisible(
+ {
+ locateStrategy: element.locateStrategy,
+ selector: element.selector,
+ timeout: timeoutHelper.parseTimeout(timeout)
+ },
+ result => {
+ isVisible = result.value === true
+ }
+ )
+ return isVisible
},
- /**
- * @returns {Promise}
- */
- isLinksPanelSelectPresent: function() {
- return this.isPanelItemPresent(this.elements.linksPanelSelect)
+ isLinksPanelSelectable: async function() {
+ return await this.isPanelSelectable('links')
},
- /**
- * @returns {Promise}
- */
- isCollaboratorsAccordionItemPresent: function() {
- return this.isPanelItemPresent(this.elements.collaboratorsPanel)
+ isSharingPanelSelectable: async function() {
+ return await this.isPanelSelectable('people')
},
markFavoriteSidebar: function() {
- return this.useXpath()
- .waitForElementVisible(this.api.page.personalPage().elements.sideBar)
+ return this.waitForElementVisible('@sidebar')
.waitForElementVisible('@fileInfoFavoriteDimm')
.click('@fileInfoFavorite')
.waitForElementVisible('@fileInfoFavoriteShining')
},
unmarkFavoriteSidebar: function() {
- return this.waitForElementVisible(this.api.page.personalPage().elements.sideBar)
+ return this.waitForElementVisible('@sidebar')
.waitForElementVisible('@fileInfoFavoriteShining')
.click('@fileInfoFavorite')
.waitForElementVisible('@fileInfoFavoriteDimm')
}
},
elements: {
+ sidebar: {
+ selector: '//*[@id="files-sidebar"]',
+ locateStrategy: 'xpath'
+ },
fileInfoIcon: {
selector: '.file_info .oc-icon'
},
@@ -181,6 +200,14 @@ module.exports = {
fileInfoFavoriteDimm: {
selector: '.oc-star-dimm'
},
+ fileInfoResourceNameAnyType: {
+ selector: `//div[contains(@id, "files-sidebar")]//span[contains(@class, "oc-resource-name") and (@data-test-resource-name=%s or @data-test-resource-path=%s)]`,
+ locateStrategy: 'xpath'
+ },
+ fileInfoResourceName: {
+ selector: `//div[contains(@id, "files-sidebar")]//span[contains(@class, "oc-resource-name") and (@data-test-resource-name=%s or @data-test-resource-path=%s) and @data-test-resource-type=%s]`,
+ locateStrategy: 'xpath'
+ },
sidebarCloseBtn: {
selector:
'//div[contains(@id, "files-sidebar")]//div[contains(@class, "is-active")]//button[contains(@class, "header__close")]',
@@ -200,23 +227,45 @@ module.exports = {
'//div[contains(@id, "files-sidebar")]//div[@class="sidebar-panel__navigation"]/button',
locateStrategy: 'xpath'
},
- linksPanelSelect: {
- selector: '#sidebar-panel-links-item-select'
- },
collaboratorsPanel: {
- selector: '#sidebar-panel-sharing-item'
+ selector: '//*[@id="sidebar-panel-sharing-item"]',
+ locateStrategy: 'xpath'
+ },
+ collaboratorsPanelMenuItem: {
+ selector: '//button[@id="sidebar-panel-sharing-item-select"]',
+ locateStrategy: 'xpath'
},
linksPanel: {
- selector: '#sidebar-panel-links-item'
+ selector: '//*[@id="sidebar-panel-links-item"]',
+ locateStrategy: 'xpath'
+ },
+ linksPanelMenuItem: {
+ selector: '//button[@id="sidebar-panel-links-item-select"]',
+ locateStrategy: 'xpath'
},
actionsPanel: {
- selector: '#sidebar-panel-actions-item'
+ selector: '//*[@id="sidebar-panel-actions-item"]',
+ locateStrategy: 'xpath'
+ },
+ actionsPanelMenuItem: {
+ selector: '//button[@id="sidebar-panel-actions-item-select"]',
+ locateStrategy: 'xpath'
},
detailsPanel: {
- selector: '#sidebar-panel-details-item'
+ selector: '//*[@id="sidebar-panel-details-item"]',
+ locateStrategy: 'xpath'
+ },
+ detailsPanelMenuItem: {
+ selector: '//button[@id="sidebar-panel-details-item-select"]',
+ locateStrategy: 'xpath'
},
versionsPanel: {
- selector: '#sidebar-panel-versions-item'
+ selector: '//*[@id="sidebar-panel-versions-item"]',
+ locateStrategy: 'xpath'
+ },
+ versionsPanelMenuItem: {
+ selector: '//button[@id="sidebar-panel-versions-item-select"]',
+ locateStrategy: 'xpath'
}
}
}
diff --git a/tests/acceptance/pageObjects/FilesPageElement/contextMenu.js b/tests/acceptance/pageObjects/FilesPageElement/contextMenu.js
new file mode 100644
index 00000000000..40df79e4f1b
--- /dev/null
+++ b/tests/acceptance/pageObjects/FilesPageElement/contextMenu.js
@@ -0,0 +1,53 @@
+module.exports = {
+ commands: {
+ /**
+ * @enum {string}
+ * @readonly
+ */
+ ContextMenuItem: Object.freeze({
+ showDetails: 'detailsButton',
+ showActions: 'actionsButton'
+ }),
+
+ /**
+ * @param {string} elementName the name of the element (mapped in `ContextMenuItem`)
+ */
+ clickMenuItem: async function(elementName) {
+ const element = this.elements[elementName]
+ await this.click(element.locateStrategy, element.selector)
+ return this
+ },
+
+ /**
+ * Clicks the menu item for showing details
+ *
+ * @returns {*}
+ */
+ showDetails: async function() {
+ await this.clickMenuItem(this.ContextMenuItem.showDetails)
+ await this.waitForAnimationToFinish() // wait for sidebar animation to finish
+ return this
+ },
+
+ /**
+ * Clicks the menu item for showing all actions
+ *
+ * @returns {*}
+ */
+ showActions: async function() {
+ await this.clickMenuItem(this.ContextMenuItem.showActions)
+ await this.waitForAnimationToFinish() // wait for sidebar animation to finish
+ return this
+ }
+ },
+ elements: {
+ detailsButton: {
+ selector: '//button[contains(@class, "oc-files-actions-show-details-trigger")]',
+ locateStrategy: 'xpath'
+ },
+ actionsButton: {
+ selector: '//button[contains(@class, "oc-files-actions-show-actions-trigger")]',
+ locateStrategy: 'xpath'
+ }
+ }
+}
diff --git a/tests/acceptance/pageObjects/FilesPageElement/fileActionsMenu.js b/tests/acceptance/pageObjects/FilesPageElement/fileActionsMenu.js
index 604dea26f98..620968a25aa 100644
--- a/tests/acceptance/pageObjects/FilesPageElement/fileActionsMenu.js
+++ b/tests/acceptance/pageObjects/FilesPageElement/fileActionsMenu.js
@@ -39,12 +39,9 @@ module.exports = {
* @throws Error
* @returns {*}
*/
- performFileAction: function(action) {
+ performFileAction: async function(action) {
const fileActionBtnSelectorXpath = this.getActionSelector(action)
- return this.useXpath()
- .waitForElementVisible(fileActionBtnSelectorXpath)
- .click(fileActionBtnSelectorXpath)
- .useCss()
+ return await this.click('xpath', fileActionBtnSelectorXpath)
},
/**
* returns the disabled state of given action
@@ -67,7 +64,7 @@ module.exports = {
* @returns {Promise<*>}
*/
delete: async function() {
- this.performFileAction(this.FileAction.delete)
+ await this.performFileAction(this.FileAction.delete)
await this.api.page.FilesPageElement.filesList().confirmDeletion()
return this
},
@@ -77,8 +74,8 @@ module.exports = {
* @return {*}
*/
rename: async function(toName, expectToSucceed = true) {
+ await this.performFileAction(this.FileAction.rename)
await this.useXpath()
- .performFileAction(this.FileAction.rename)
.waitForElementVisible('@dialog')
.waitForAnimationToFinish() // wait for transition on the modal to finish
.clearValue('@dialogInput')
@@ -96,33 +93,33 @@ module.exports = {
* mark as favorite resource using fileActions 'favorite' button
* @returns {Promise<*>}
*/
- favorite: function() {
- return this.performFileAction(this.FileAction.favorite)
+ favorite: async function() {
+ return await this.performFileAction(this.FileAction.favorite)
},
/**
* unmark as favorite resource using fileActions 'favorite' button
* @returns {Promise<*>}
*/
- unmarkFavorite: function() {
- return this.performFileAction(this.FileAction.unmarkFavorite)
+ unmarkFavorite: async function() {
+ return await this.performFileAction(this.FileAction.unmarkFavorite)
},
/**
* @return {Promise}
*/
- restore: function() {
- return this.performFileAction(this.FileAction.restore)
+ restore: async function() {
+ return await this.performFileAction(this.FileAction.restore)
},
/**
* @return {Promise}
*/
- download: function() {
- return this.performFileAction(this.FileAction.download)
+ download: async function() {
+ return await this.performFileAction(this.FileAction.download)
},
/**
* @return {Promise}
*/
deleteResourceImmediately: async function() {
- this.performFileAction(this.FileAction.delete)
+ await this.performFileAction(this.FileAction.delete)
await this.api.page.FilesPageElement.filesList().confirmDeletion()
return this
@@ -130,14 +127,14 @@ module.exports = {
/**
* Trigger the move of a resource via its file action
*/
- move: function() {
- return this.performFileAction(this.FileAction.move)
+ move: async function() {
+ return await this.performFileAction(this.FileAction.move)
},
/**
* Trigger the copy of a resource via its file action
*/
- copy: function() {
- return this.performFileAction(this.FileAction.copy)
+ copy: async function() {
+ return await this.performFileAction(this.FileAction.copy)
},
/**
* Trigger accepting a share
diff --git a/tests/acceptance/pageObjects/FilesPageElement/filesList.js b/tests/acceptance/pageObjects/FilesPageElement/filesList.js
index 8bca2c7c0fa..83b2a114db2 100644
--- a/tests/acceptance/pageObjects/FilesPageElement/filesList.js
+++ b/tests/acceptance/pageObjects/FilesPageElement/filesList.js
@@ -2,8 +2,10 @@ const util = require('util')
const assert = require('assert')
const xpathHelper = require('../../helpers/xpath')
const { client } = require('nightwatch-api')
+const appSideBar = client.page.FilesPageElement.appSideBar()
+const contextMenu = client.page.FilesPageElement.contextMenu()
const filesRow = client.page.FilesPageElement.filesRow()
-const filesActionsMenu = client.page.FilesPageElement.fileActionsMenu()
+const fileActionsMenu = client.page.FilesPageElement.fileActionsMenu()
module.exports = {
commands: {
@@ -12,10 +14,16 @@ module.exports = {
* @return {Promise<*>}
*/
openSharingDialog: async function(resource) {
- const appSidebar = client.page.FilesPageElement.appSideBar()
- await appSidebar.closeSidebar(500)
await this.openSideBar(resource)
- return client.page.FilesPageElement.appSideBar().activatePanel('people')
+ return await appSideBar.activatePanel('people')
+ },
+ /**
+ * @param {string} resource
+ * @return {Promise<*>}
+ */
+ openPublicLinkDialog: async function(resource) {
+ await this.openSideBar(resource)
+ return await appSideBar.activatePanel('links')
},
/**
* @param {string} resource
@@ -31,128 +39,119 @@ module.exports = {
return this.useXpath().waitForElementNotPresent(previewSelector)
},
- /**
- * @param {string} fileName
- * @return {Promise<*>}
- */
- openPublicLinkDialog: async function(fileName) {
- await this.waitForFileVisible(fileName)
- await this.openSideBar(fileName)
- return client.page.FilesPageElement.appSideBar().activatePanel('links')
- },
/**
* @param {string} resource
+ * @param {string} elementType
* @return {Promise}
*/
- deleteFile: async function(resource) {
- await this.waitForFileVisible(resource)
- await filesRow.openFileActionsMenu(resource)
- await filesActionsMenu.delete()
+ deleteFile: async function(resource, elementType = 'any') {
+ await this.openFileActionsMenu(resource, elementType)
+ await fileActionsMenu.delete()
return this
},
/**
* @param {string} resource
+ * @param {string} elementType
* @returns {Promise}
*/
- acceptShare: async function(resource) {
- await this.waitForFileVisible(resource)
- await filesRow.openFileActionsMenu(resource)
- await filesActionsMenu.acceptShare()
+ acceptShare: async function(resource, elementType = 'any') {
+ await this.openFileActionsMenu(resource, elementType)
+ await fileActionsMenu.acceptShare()
return this
},
/**
* @param {string} resource
+ * @param {string} elementType
* @returns {Promise}
*/
- declineShare: async function(resource) {
- await this.waitForFileVisible(resource)
- await filesRow.openFileActionsMenu(resource)
- await filesActionsMenu.declineShare()
+ declineShare: async function(resource, elementType = 'any') {
+ await this.openFileActionsMenu(resource, elementType)
+ await fileActionsMenu.declineShare()
return this
},
/**
* @param {string} fromName
* @param {string} toName
* @param {boolean} expectToSucceed
+ * @param {string} elementType
* @return {Promise}
*/
- renameFile: async function(fromName, toName, expectToSucceed = true) {
- await this.waitForFileVisible(fromName)
- await filesRow.openFileActionsMenu(fromName)
- await filesActionsMenu.rename(toName, expectToSucceed)
+ renameFile: async function(fromName, toName, expectToSucceed = true, elementType = 'any') {
+ await this.openFileActionsMenu(fromName, elementType)
+ await fileActionsMenu.rename(toName, expectToSucceed)
return this
},
/**
- * @param {string} path
+ * @param {string} resource
+ * @param {string} elementType
* @return {Promise}
*/
- markFavorite: async function(path) {
- await this.waitForFileVisible(path)
- await filesRow.openFileActionsMenu(path)
- await filesActionsMenu.favorite()
+ markFavorite: async function(resource, elementType = 'any') {
+ await this.openFileActionsMenu(resource, elementType)
+ await fileActionsMenu.favorite()
return this
},
/**
- * @param {string} path
+ * @param {string} resource
+ * @param {string} elementType
* @return {Promise}
*/
- unmarkFavorite: async function(path) {
- await this.waitForFileVisible(path)
- await filesRow.openFileActionsMenu(path)
- await filesActionsMenu.unmarkFavorite()
+ unmarkFavorite: async function(resource, elementType = 'any') {
+ await this.openFileActionsMenu(resource, elementType)
+ await fileActionsMenu.unmarkFavorite()
return this
},
/**
- * @param {string} element
+ * @param {string} resource
* @param {string} elementType
* @return {Promise}
*/
- restoreFile: async function(element, elementType) {
- await this.waitForFileWithPathVisible(element, elementType)
- await filesRow.openFileActionsMenu(element, elementType)
- await filesActionsMenu.restore()
+ restoreFile: async function(resource, elementType = 'any') {
+ await this.openFileActionsMenu(resource, elementType)
+ await fileActionsMenu.restore()
return this
},
/**
* @param {string} resource
+ * @param {string} elementType
* @return {Promise}
*/
- deleteImmediately: async function(resource) {
- await this.waitForFileVisible(resource)
- await filesRow.openFileActionsMenu(resource)
- await filesActionsMenu.deleteResourceImmediately(resource)
+ deleteImmediately: async function(resource, elementType = 'any') {
+ await this.openFileActionsMenu(resource, elementType)
+ await fileActionsMenu.deleteResourceImmediately()
return this
},
/**
* @param {string} action
* @param {string} resource
+ * @param {string} elementType
* @return {Promise}
*/
- isActionAttributeDisabled: async function(action, resource) {
- await this.waitForFileVisible(resource)
- await filesRow.openFileActionsMenu(resource)
- return await filesActionsMenu.getActionDisabledAttr('delete')
+ isActionAttributeDisabled: async function(action, resource, elementType = 'any') {
+ await this.openFileActionsMenu(resource, elementType)
+ return await fileActionsMenu.getActionDisabledAttr('delete')
},
/**
* @param {string} resource
+ * @param {string} elementType
* @return {Promise}
*/
- downloadFile: async function(resource) {
- await this.waitForFileVisible(resource)
- await filesRow.openFileActionsMenu(resource)
- await filesActionsMenu.download()
+ downloadFile: async function(resource, elementType = 'any') {
+ await this.openFileActionsMenu(resource, elementType)
+ await fileActionsMenu.download()
return this
},
/**
* @param {string} resource
+ * @param {string} elementType
* @return {Promise}
*/
- isSharingButtonPresent: async function(resource) {
+ isSharingButtonPresent: async function(resource, elementType = 'any') {
const sharingBtnSelector = util.format(
filesRow.elements.quickAction.selector,
'collaborators'
)
- const resourceRowSelector = this.getFileRowSelectorByFileName(resource)
+ const resourceRowSelector = this.getFileRowSelectorByFileName(resource, elementType)
let isPresent = true
await this.api.elements(
@@ -188,15 +187,71 @@ module.exports = {
return this
},
+ /**
+ * opens context menu for given resource
+ *
+ * @param {string} resource The name or path of a resource
+ * @param {string} elementType The resource type (file|folder|any)
+ * @returns {*}
+ */
+ openContextMenu: async function(resource, elementType = 'any') {
+ await this.waitForFileVisible(resource, elementType)
+ const selectorContextMenu =
+ this.getFileRowSelectorByFileName(resource, elementType) +
+ this.elements.contextBtnInFileRow.selector
+ await this.click('xpath', selectorContextMenu)
+ await this.waitForElementVisible('@contextMenuPanel')
+ return contextMenu
+ },
+
+ /**
+ * opens file-actions menu for given resource
+ *
+ * @param {string} resource The resource name
+ * @param {string} elementType The resource type (file|folder|any)
+ *
+ * @returns {*}
+ */
+ openFileActionsMenu: async function(resource, elementType = 'any') {
+ await this.openSideBar(resource, elementType)
+ await appSideBar.activatePanel('actions')
+ return fileActionsMenu
+ },
+
/**
* opens sidebar for given resource
*
* @param {string} resource
+ * @param {string} elementType The resource type (file|folder|any)
* @returns {*}
*/
- openSideBar: async function(resource) {
- await this.clickRow(resource)
- return this.api.page.FilesPageElement.appSideBar()
+ openSideBar: async function(resource, elementType = 'any') {
+ // nothing to do if already open for correct resource
+ if (await appSideBar.isSideBarOpenForResource(resource, elementType)) {
+ return appSideBar
+ }
+
+ // open the sidebar for the resource
+ await this.clickRow(resource, elementType)
+ await this.click('@btnToggleSideBar')
+ await this.waitForAnimationToFinish() // wait for the sidebar animation to finish
+ return appSideBar
+ },
+ /**
+ * @param {string} resource the file/folder to click
+ * @param {string} elementType The resource type (file|folder|any)
+ */
+ clickRow: async function(resource, elementType = 'any') {
+ await this.waitForFileVisible(resource, elementType)
+ await this.initAjaxCounters()
+ .useXpath()
+ // click in empty space in the tr using coordinates to avoid
+ // clicking on other elements that might be in the front
+ .clickElementAt(this.getFileRowSelectorByFileName(resource, elementType), 1, 1)
+ .waitForOutstandingAjaxCalls()
+ .useCss()
+
+ return this
},
/**
*
@@ -218,19 +273,6 @@ module.exports = {
.waitForOutstandingAjaxCalls()
.useCss()
},
- /**
- * @param {string} item the file/folder to click
- */
- clickRow: async function(item) {
- await this.waitForFileVisible(item)
- const selectorXPath =
- this.getFileRowSelectorByFileName(item) + this.elements.detailsBtnInFileRow.selector
- await this.click({
- selector: selectorXPath,
- locateStrategy: 'xpath'
- }).waitForAjaxCallsToStartAndFinish()
- return this
- },
/**
* Toggle enable or disable file/folder select checkbox
@@ -265,10 +307,6 @@ module.exports = {
})
return selectionStatus
},
- waitForTableLoaded: async function() {
- await this.waitForElementVisible('@filesTable')
- return this
- },
waitForLoadingFinished: async function(awaitVisible = true, abortOnFailure = true) {
if (awaitVisible) {
await this.waitForElementVisible({ selector: '@anyAfterLoading', abortOnFailure })
@@ -308,7 +346,7 @@ module.exports = {
waitForFileVisible: async function(fileName, elementType = 'any') {
const rowSelector = this.getFileRowSelectorByFileName(fileName, elementType)
- await client.page.FilesPageElement.appSideBar().closeSidebar(500)
+ await appSideBar.closeSidebarIfOpen()
let rowElementId = null
await this.waitForElementPresent(
{ selector: rowSelector, locateStrategy: 'xpath' },
@@ -320,7 +358,6 @@ module.exports = {
await this.api.elementIdLocation(rowElementId, result => {
offset = result.value.y
})
-
let firstRowElementId = null
await this.waitForElementPresent('@fileRow', result => {
firstRowElementId = result.WebdriverElementId
@@ -330,29 +367,8 @@ module.exports = {
})
this.api.execute('scrollTo(0,' + offset + ')')
-
return this
},
- /**
- * Wait for a filerow with given path to be visible
- * This only works in the favorites page as it uses the whole path of a file rather than just the name
- * This does not works in cases where the path starts with a space (eg. " ParentFolder/file.txt")
- *
- * @param {string} path
- * @param {string} elementType
- */
- waitForFileWithPathVisible: async function(path, elementType = 'any') {
- await client.page.FilesPageElement.appSideBar().closeSidebar(500)
- const linkSelector = this.getFileLinkSelectorByFileName(path, elementType)
- const rowSelector = this.getFileRowSelectorByFileName(path, elementType)
- return this.useXpath()
- .waitForElementVisible(rowSelector)
- .waitForElementVisible(linkSelector)
- .getText(linkSelector, function(result) {
- assert.strictEqual(result.value.trim(), path, 'displayed file name not as expected')
- })
- .useCss()
- },
/**
*
* @param {string} fileName
@@ -541,39 +557,22 @@ module.exports = {
return this.useCss()
},
- /**
- * Returns original string with replaced target character
- * @param {string} string String in which will be the target character replaced
- * @param {string} targetChar Target character which is to be replaced
- * @param {string} newChar New character which will replace target character
- * @returns {string} String with replaced target character
- */
- replaceChar: function(string, targetChar, newChar) {
- const regex = new RegExp(targetChar, 'g')
- return string.replace(regex, newChar)
- },
-
useQuickAction: async function(resource, action) {
action = action.replace(/\s/, '-')
- const actionSelector = util.format(
- this.api.page.FilesPageElement.filesRow().elements.quickAction.selector,
- action
- )
+ const actionSelector = util.format(filesRow.elements.quickAction.selector, action)
const resourceRowSelector = this.getFileRowSelectorByFileName(resource)
await this.waitForFileVisible(resource)
- return this.useXpath()
- .click(resourceRowSelector + actionSelector)
- .useCss()
+ await this.click('xpath', resourceRowSelector + actionSelector)
+ await this.waitForAnimationToFinish() // wait for the sidebar animation to finish
+ return this
},
moveResource: async function(resource, target) {
- await this.waitForFileVisible(resource)
-
// Trigger move
- await filesRow.openFileActionsMenu(resource)
- await filesActionsMenu.move()
+ await this.openFileActionsMenu(resource)
+ await fileActionsMenu.move()
// Execute move
await client.page.locationPicker().selectFolderAndConfirm(target)
@@ -581,19 +580,6 @@ module.exports = {
return this
},
- attemptToMoveResource: async function(resource, target) {
- await this.waitForFileVisible(resource)
-
- // Trigger move
- await filesRow.openFileActionsMenu(resource)
- await filesActionsMenu.move()
-
- // select folder
- await client.page.locationPicker().selectFolder(target)
-
- return this
- },
-
cancelResourceMoveOrCopyProgress: async function() {
// cancel copy or move
await this.waitForElementVisible(this.elements.cancelMoveCopyBtn.selector).click(
@@ -605,11 +591,9 @@ module.exports = {
},
copyResource: async function(resource, target) {
- await this.waitForFileVisible(resource)
-
// Trigger copy
- await filesRow.openFileActionsMenu(resource)
- await filesActionsMenu.copy()
+ await this.openFileActionsMenu(resource)
+ await fileActionsMenu.copy()
// Execute copy
await client.page.locationPicker().selectFolderAndConfirm(target)
@@ -617,18 +601,6 @@ module.exports = {
return this
},
- attemptToCopyResource: async function(resource, target) {
- await this.waitForFileVisible(resource)
-
- // Trigger copy
- await filesRow.openFileActionsMenu(resource)
- await filesActionsMenu.copy()
-
- // Execute copy
- await client.page.locationPicker().selectFolder(target)
-
- return this
- },
clickOnFileName: function(fileName) {
const file = this.getFileLinkSelectorByFileName(fileName, 'file')
return this.useXpath()
@@ -698,10 +670,13 @@ module.exports = {
'//span[contains(@class, "oc-resource-name") and (@data-test-resource-name=%s or @data-test-resource-path=%s) and @data-test-resource-type=%s]/parent::*',
locateStrategy: 'xpath'
},
- detailsBtnInFileRow: {
- selector: '//button[contains(@class, "oc-table-files-btn-show-details")]',
+ contextBtnInFileRow: {
+ selector: '//button[contains(@class, "oc-table-files-btn-action-dropdown")]',
locateStrategy: 'xpath'
},
+ contextMenuPanel: {
+ selector: 'ul#oc-files-context-actions'
+ },
/**
* This element is concatenated as child of @see fileRowByResourcePath
*/
@@ -765,6 +740,9 @@ module.exports = {
},
cancelMoveCopyBtn: {
selector: '#location-picker-btn-cancel'
+ },
+ btnToggleSideBar: {
+ selector: '#files-toggle-sidebar'
}
}
}
diff --git a/tests/acceptance/pageObjects/FilesPageElement/filesRow.js b/tests/acceptance/pageObjects/FilesPageElement/filesRow.js
index 70d1562fbbb..2144550a082 100644
--- a/tests/acceptance/pageObjects/FilesPageElement/filesRow.js
+++ b/tests/acceptance/pageObjects/FilesPageElement/filesRow.js
@@ -1,43 +1,8 @@
/* eslint-disable no-unused-expressions */
-const { client } = require('nightwatch-api')
const util = require('util')
-const filesList = client.page.FilesPageElement.filesList()
module.exports = {
commands: {
- /**
- * Get Selector for File Actions expander
- *
- * @param {string} fileName
- * @param {string} elementType
- * @returns {string} file action button selector
- */
- getFileActionBtnSelector: function(fileName, elementType = 'any') {
- return (
- filesList.getFileRowSelectorByFileName(fileName, elementType) +
- this.elements.fileActionsButtonInFileRow.selector
- )
- },
- /**
- * opens file-actions menu for given resource
- *
- * @param {string} resource The resource name
- * @param {string} elementType The resource type (file|folder)
- *
- * @returns {*}
- */
- openFileActionsMenu: async function(resource, elementType = 'any') {
- const fileActionsBtnSelector = this.getFileActionBtnSelector(resource, elementType)
- this.useXpath()
- .initAjaxCounters()
- .waitForElementVisible(fileActionsBtnSelector)
- .click(fileActionsBtnSelector)
- .waitForOutstandingAjaxCalls()
- .waitForAnimationToFinish()
- .useCss()
- await this.api.page.FilesPageElement.appSideBar().activatePanel('actions')
- return await this.api.page.FilesPageElement.fileActionsMenu()
- },
isQuickActionVisible: function(action) {
action = action.replace(/\s/, '-')
const actionSelector = util.format(this.elements.quickAction.selector, action)
@@ -49,10 +14,6 @@ module.exports = {
}
},
elements: {
- fileActionsButtonInFileRow: {
- selector: '//button[contains(@class, "oc-table-files-btn-show-details")]',
- locateStrategy: 'xpath'
- },
quickAction: {
selector: '//button[contains(@class, "files-quick-action-%s")]',
locateStrategy: 'xpath'
diff --git a/tests/acceptance/pageObjects/FilesPageElement/mediaViewerPage.js b/tests/acceptance/pageObjects/FilesPageElement/mediaViewerPage.js
index d8180999e6a..da2d023106d 100644
--- a/tests/acceptance/pageObjects/FilesPageElement/mediaViewerPage.js
+++ b/tests/acceptance/pageObjects/FilesPageElement/mediaViewerPage.js
@@ -1,12 +1,12 @@
const util = require('util')
const { client } = require('nightwatch-api')
-const filesRow = client.page.FilesPageElement.filesRow()
+const filesList = client.page.FilesPageElement.filesList()
const filesActionsMenu = client.page.FilesPageElement.fileActionsMenu()
module.exports = {
commands: {
openMediaViewer: async function(fileName) {
- await filesRow.openFileActionsMenu(fileName)
+ await filesList.openFileActionsMenu(fileName)
await filesActionsMenu.mediaViewer()
return this
diff --git a/tests/acceptance/pageObjects/FilesPageElement/sharingDialog.js b/tests/acceptance/pageObjects/FilesPageElement/sharingDialog.js
index 0d3ae855d85..e40a9afb779 100644
--- a/tests/acceptance/pageObjects/FilesPageElement/sharingDialog.js
+++ b/tests/acceptance/pageObjects/FilesPageElement/sharingDialog.js
@@ -88,24 +88,26 @@ module.exports = {
// We need waitForElementPresent here.
// waitForElementVisible would break even with 'abortOnFailure: false' if the element is not present
- await this.enterAutoComplete(sharee).waitForElementPresent(
- {
- selector: '@sharingAutoCompleteDropDownElements',
- abortOnFailure: false
- },
+ let failedOnFirstTry = false
+ await this.enterAutoComplete(sharee)
+ const dropdownElement = this.elements.sharingAutoCompleteDropDownElements
+ await this.waitForElementVisible(
+ dropdownElement.locateStrategy,
+ dropdownElement.selector,
+ this.api.globals.waitForConditionTimeout,
+ this.api.globals.waitForConditionPollInterval,
+ false,
result => {
- if (result.value === false) {
- // sharing dropdown was not shown
- console.log('WARNING: no sharing autocomplete dropdown found, retry typing')
- this.clearValue('@sharingAutoComplete')
- .enterAutoComplete(sharee)
- .waitForElementPresent({
- selector: '@sharingAutoCompleteDropDownElements',
- abortOnFailure: false
- })
- }
+ failedOnFirstTry = result.status === -1
}
)
+ if (failedOnFirstTry) {
+ // sharing dropdown was not shown. Try a second time.
+ console.log('WARNING: no sharing autocomplete dropdown found, retry typing')
+ await this.clearValue('@sharingAutoComplete')
+ await this.enterAutoComplete(sharee)
+ await this.waitForElementVisible(dropdownElement.selector)
+ }
let receiverType = shareWithGroup === true ? SHARE_TYPE_STRING.group : SHARE_TYPE_STRING.user
receiverType = remoteShare === true ? SHARE_TYPE_STRING.federation : receiverType
@@ -144,7 +146,6 @@ module.exports = {
* @param {string} permissions
* @param {boolean} remote
* @param {string} days
- * @param {boolean} quickAction Asserts whether the quick actions should be used to open new collaborators panel
*
* @return void
*/
@@ -309,11 +310,11 @@ module.exports = {
*
* @param {string} input
*/
- enterAutoComplete: function(input) {
- return this.waitForElementVisible('@sharingAutoComplete')
- .initAjaxCounters()
- .setValueBySingleKeys('@sharingAutoComplete', input)
- .waitForAjaxCallsToStartAndFinish()
+ enterAutoComplete: async function(input) {
+ await this.waitForElementVisible('@sharingAutoComplete')
+ await this.initAjaxCounters()
+ await this.setValueBySingleKeys('@sharingAutoComplete', input)
+ await this.waitForAjaxCallsToStartAndFinish()
},
/**
*
@@ -339,27 +340,24 @@ module.exports = {
*/
getShareAutocompleteWebElementIdList: async function() {
const webElementIdList = []
- const showAllResultsXpath = this.elements.sharingAutoCompleteShowAllResultsButton.selector
+ const showAllResultsElement = this.elements.sharingAutoCompleteShowAllResultsButton
// wait for autocomplete to finish loading
- try {
- await this.waitForElementVisible('@sharingAutoCompleteDropDown')
- } catch (e) {
- // FIXME: the dropdown will not appear when there are zero results
- // (https://github.com/owncloud/owncloud-design-system/issues/547)
- // so need to catch the error here
- return []
- }
+ await this.waitForElementVisible('@sharingAutoCompleteDropDown')
await this.waitForElementNotPresent('@sharingAutoCompleteSpinner')
// note: some result lists don't have the "show all" button depending on the number of entries,
// so we only click it if present
- await this.api.element('css selector', showAllResultsXpath, result => {
- if (result.status !== -1) {
- return this.click('@sharingAutoCompleteShowAllResultsButton')
+ await this.api.element(
+ showAllResultsElement.locateStrategy,
+ showAllResultsElement.selector,
+ result => {
+ if (result.status !== -1) {
+ return this.click('@sharingAutoCompleteShowAllResultsButton')
+ }
}
- })
+ )
await this.api.elements(
- 'css selector',
+ this.elements.sharingAutoCompleteDropDownElements.locateStrategy,
this.elements.sharingAutoCompleteDropDownElements.selector,
result => {
result.value.forEach(value => {
@@ -630,10 +628,13 @@ module.exports = {
selector: '#files-share-invite .vs__dropdown-menu'
},
sharingAutoCompleteDropDownElements: {
- selector: '#files-share-invite .vs__dropdown-menu .files-collaborators-autocomplete-user-text'
+ selector:
+ '#files-share-invite .vs__dropdown-menu .files-collaborators-autocomplete-user-text',
+ locateStrategy: 'css selector'
},
sharingAutoCompleteShowAllResultsButton: {
- selector: '.oc-autocomplete-suggestion-overflow'
+ selector: '.oc-autocomplete-suggestion-overflow',
+ locateStrategy: 'css selector'
},
sharedWithListItem: {
selector: '//*[@id="file-share-list"]//*[@class="oc-user"]//div[.="%s"]/../..',
diff --git a/tests/acceptance/pageObjects/markdownEditorPage.js b/tests/acceptance/pageObjects/markdownEditorPage.js
index 1bbc9695653..233e15b1364 100644
--- a/tests/acceptance/pageObjects/markdownEditorPage.js
+++ b/tests/acceptance/pageObjects/markdownEditorPage.js
@@ -1,7 +1,6 @@
const { client } = require('nightwatch-api')
const filesList = client.page.FilesPageElement.filesList()
-const filesRow = client.page.FilesPageElement.filesRow()
const filesActionsMenu = client.page.FilesPageElement.fileActionsMenu()
module.exports = {
@@ -72,8 +71,7 @@ module.exports = {
* @param {string} fileName
*/
openMdEditorUsingActionMenu: async function(fileName) {
- await filesList.waitForFileVisible(fileName)
- await filesRow.openFileActionsMenu(fileName)
+ await filesList.openFileActionsMenu(fileName)
await filesActionsMenu.markdownEditor()
return this
}
diff --git a/tests/acceptance/pageObjects/personalPage.js b/tests/acceptance/pageObjects/personalPage.js
index 87b23278d1e..c8fa4e9af17 100644
--- a/tests/acceptance/pageObjects/personalPage.js
+++ b/tests/acceptance/pageObjects/personalPage.js
@@ -1,6 +1,5 @@
const util = require('util')
const xpathHelper = require('../helpers/xpath')
-const timeoutHelper = require('../helpers/timeoutHelper')
const { join, normalize } = require('../helpers/path')
const { client } = require('nightwatch-api')
@@ -235,30 +234,6 @@ module.exports = {
.waitForAjaxCallsToStartAndFinish()
.waitForElementNotPresent('@dialog')
},
- isSidebarVisible: async function(timeout = null) {
- let isVisible = false
- timeout = timeoutHelper.parseTimeout(timeout)
- await this.isVisible(
- {
- locateStrategy: this.elements.sideBar.locateStrategy,
- selector: this.elements.sideBar.selector,
- timeout: timeout
- },
- result => {
- isVisible = result.status === 0
- }
- )
- return isVisible
- },
- checkSidebarItem: function(resourceName) {
- return this.getText('@sidebarItemName', function(itemName) {
- this.assert.strictEqual(
- itemName.value,
- resourceName,
- `In sidebar is different item - ${itemName.value}`
- )
- })
- },
confirmFileOverwrite: async function() {
await this.waitForAnimationToFinish() // wait for transition on the modal to finish
.click('@dialogConfirmBtnEnabled')
@@ -418,13 +393,6 @@ module.exports = {
fileUploadProgress: {
selector: '#files-upload-progress'
},
- sideBar: {
- selector: '//div[contains(@id, "files-sidebar")]',
- locateStrategy: 'xpath'
- },
- sidebarItemName: {
- selector: '.sidebar-panel.is-active h2'
- },
dialog: {
selector: '.oc-modal'
},
diff --git a/tests/acceptance/pageObjects/webPage.js b/tests/acceptance/pageObjects/webPage.js
index 9e179287b85..c80872a154e 100644
--- a/tests/acceptance/pageObjects/webPage.js
+++ b/tests/acceptance/pageObjects/webPage.js
@@ -201,11 +201,12 @@ module.exports = {
browseToUserProfile: function() {
return this.click('@userMenuButton')
},
- getDisplayedMessage: async function() {
+ getDisplayedMessage: async function(titleOnly = false) {
let element = ''
let displayedmessage
- await this.waitForElementVisible('@messages')
- await this.api.element('@messages', result => {
+ const selector = titleOnly ? '@message' : '@messages'
+ await this.waitForElementVisible(selector)
+ await this.api.element(selector, result => {
element = result.value.ELEMENT
})
await this.api.elementIdText(element, function(result) {
diff --git a/tests/acceptance/stepDefinitions/filesContext.js b/tests/acceptance/stepDefinitions/filesContext.js
index a3e69e5fdf6..5f5e1a8b7e1 100644
--- a/tests/acceptance/stepDefinitions/filesContext.js
+++ b/tests/acceptance/stepDefinitions/filesContext.js
@@ -134,8 +134,8 @@ When('the user browses to display the {string} details of file {string}', async
filename
) {
const api = client.page.FilesPageElement
- await api.filesList().clickRow(filename)
await client.initAjaxCounters()
+ await api.filesList().openSideBar(filename)
await api.appSideBar().activatePanel(accordionItem)
await client.waitForOutstandingAjaxCalls()
@@ -177,8 +177,8 @@ Given('the user has opened the share dialog for file/folder {string}', function(
return client.page.FilesPageElement.filesList().openSharingDialog(fileName)
})
-When('the user closes the app-sidebar using the webUI', function() {
- return client.page.FilesPageElement.appSideBar().closeSidebar(100)
+When('the user closes the app-sidebar using the webUI', async function() {
+ return await client.page.FilesPageElement.appSideBar().closeSidebarIfOpen()
})
When('the user browses to folder {string} using the breadcrumb on the webUI', resource =>
@@ -367,7 +367,7 @@ When('the user marks file/folder {string} as favorite using the webUI sidebar',
path
) {
const api = client.page.FilesPageElement
- await api.filesList().clickRow(path)
+ await api.filesList().openSideBar(path)
api.appSideBar().markFavoriteSidebar()
return client
})
@@ -376,7 +376,7 @@ When('the user unmarks the favorited file/folder {string} using the webUI sideba
path
) {
const api = client.page.FilesPageElement
- await api.filesList().clickRow(path)
+ await api.filesList().openSideBar(path)
api.appSideBar().unmarkFavoriteSidebar()
return client
})
@@ -422,7 +422,7 @@ Then('folder {string} should be listed on the webUI', folder => {
})
Then('file/folder with path {string} should be listed on the webUI', function(path) {
- return client.page.FilesPageElement.filesList().waitForFileWithPathVisible(path)
+ return client.page.FilesPageElement.filesList().waitForFileVisible(path)
})
Then('the last uploaded folder should be listed on the webUI', async function() {
@@ -485,16 +485,15 @@ Then('the versions list for resource {string} should contain {int} entry/entries
expectedNumber
) {
const api = client.page.FilesPageElement
- await api.filesList().clickRow(resourceName)
await client.initAjaxCounters()
+ await api.filesList().openSideBar(resourceName)
await api.appSideBar().activatePanel('versions')
await client.waitForOutstandingAjaxCalls()
const count = await api.versionsDialog().getVersionsCount()
assert.strictEqual(count, expectedNumber)
- client.page.FilesPageElement.appSideBar().closeSidebar(100)
-
+ await api.appSideBar().closeSidebarIfOpen()
return this
})
@@ -599,8 +598,8 @@ When('the user batch restores the marked files using the webUI', function() {
return client.page.FilesPageElement.filesList().restoreSelected()
})
-When('the user picks the row of file/folder {string} on the webUI', function(item) {
- return client.page.FilesPageElement.filesList().clickRow(item)
+When('the user opens the sidebar for file/folder {string} on the webUI', function(item) {
+ return client.page.FilesPageElement.filesList().openSideBar(item)
})
When('the user switches to {string} panel in details panel using the webUI', function(item) {
@@ -822,20 +821,20 @@ Then('as user {string} file/folder {string} should not be marked as favorite', a
Then('file/folder {string} should be marked as favorite on the webUI', async function(path) {
const selector = client.page.FilesPageElement.appSideBar().elements.fileInfoFavoriteShining
- await client.page.FilesPageElement.filesList().clickRow(path)
+ await client.page.FilesPageElement.filesList().openSideBar(path)
client.expect.element(selector).to.be.present
- client.page.FilesPageElement.appSideBar().closeSidebar()
+ await client.page.FilesPageElement.appSideBar().closeSidebarIfOpen()
return client
})
Then('file/folder {string} should not be marked as favorite on the webUI', async function(path) {
const selector = client.page.FilesPageElement.appSideBar().elements.fileInfoFavoriteDimm
- await client.page.FilesPageElement.filesList().clickRow(path)
+ await client.page.FilesPageElement.filesList().openSideBar(path)
client.expect.element(selector).to.be.present
- client.page.FilesPageElement.appSideBar().closeSidebar()
+ await client.page.FilesPageElement.appSideBar().closeSidebarIfOpen()
return client
})
@@ -848,14 +847,12 @@ Then(/the count of files and folders shown on the webUI should be (\d+)/, async
})
Then('the app-sidebar should be visible', async function() {
- const visible = await client.page.personalPage().isSidebarVisible()
+ const visible = await client.page.FilesPageElement.appSideBar().isSideBarOpen()
assert.strictEqual(visible, true, 'app-sidebar should be visible, but is not')
})
Then('the app-sidebar should be invisible', async function() {
- const visible = await client.page
- .personalPage()
- .isSidebarVisible(client.globals.waitForNegativeConditionTimeout)
+ const visible = await client.page.FilesPageElement.appSideBar().isSideBarOpen()
assert.strictEqual(visible, false, 'app-sidebar should be invisible, but is not')
})
@@ -1018,18 +1015,21 @@ Then(
)
When(
- 'the user opens the actions sidebar panel of file/folder {string} on the webUI',
- async function(resource) {
- await client.page.FilesPageElement.filesRow().openFileActionsMenu(resource)
+ /^the user opens the actions sidebar panel of (file|folder) "([^"]*)" on the webUI$/,
+ async function(elementType, resource) {
+ await client.page.FilesPageElement.filesList().openFileActionsMenu(resource, elementType)
}
)
-Then('the app-sidebar for file/folder {string} should be visible on the webUI', async function(
+Then(/^the app-sidebar for (file|folder) "([^"]*)" should be visible on the webUI$/, async function(
+ elementType,
resource
) {
- const visible = await client.page.personalPage().isSidebarVisible()
+ const visible = await client.page.FilesPageElement.appSideBar().isSideBarOpenForResource(
+ resource,
+ elementType
+ )
assert.strictEqual(visible, true, 'app-sidebar should be visible, but is not')
- return client.page.personalPage().checkSidebarItem(resource)
})
Then('the thumbnail should be visible in the app-sidebar', function() {
@@ -1257,8 +1257,8 @@ Then('the move here file/folder button should be disabled', function() {
When('the user selects move action for folder/file {string} using the webUI', async function(
resource
) {
- await client.page.FilesPageElement.filesRow().openFileActionsMenu(resource)
- return client.page.FilesPageElement.fileActionsMenu().move()
+ await client.page.FilesPageElement.filesList().openFileActionsMenu(resource)
+ return await client.page.FilesPageElement.fileActionsMenu().move()
})
When('the user cancels the attempt to move/copy resources using the webUI', function() {
@@ -1311,18 +1311,11 @@ When('the user tries to copy file/folder {string} into folder {string} using the
})
})
-When('the user opens the file action menu of file/folder {string} using the webUI', async function(
- resource
-) {
- await client.page.FilesPageElement.filesList().waitForFileVisible(resource)
- await client.page.FilesPageElement.filesRow().openFileActionsMenu(resource)
-})
-
When('the user selects copy action for file/folder {string} using the webUI', async function(
resource
) {
- await client.page.FilesPageElement.filesRow().openFileActionsMenu(resource)
- return client.page.FilesPageElement.fileActionsMenu().copy()
+ await client.page.FilesPageElement.filesList().openFileActionsMenu(resource)
+ return await client.page.FilesPageElement.fileActionsMenu().copy()
})
When(
@@ -1393,16 +1386,6 @@ Then(
}
)
-Given('the app-sidebar for file/folder {string} has been visible on the webUI', async function(
- resource
-) {
- await client.page.FilesPageElement.filesList().clickRow(resource)
-
- const visible = await client.page.personalPage().isSidebarVisible()
- assert.strictEqual(visible, true, 'app-sidebar should be visible, but is not')
- return client.page.personalPage().checkSidebarItem(resource)
-})
-
Then(
'only the following items with default items should be visible in the actions menu on the webUI',
async function(table) {
@@ -1420,7 +1403,7 @@ Then(
assert.strictEqual(
isPresent,
true,
- `only '${expectedVisibleItems}' actions menu item(s) was expected to be visible but also found '${visibleItems}'.`
+ `only '${expectedVisibleItems}' actions menu item(s) was expected to be visible but found '${visibleItems}' instead.`
)
}
)
diff --git a/tests/acceptance/stepDefinitions/generalContext.js b/tests/acceptance/stepDefinitions/generalContext.js
index f813cb76e40..26fc05d1978 100644
--- a/tests/acceptance/stepDefinitions/generalContext.js
+++ b/tests/acceptance/stepDefinitions/generalContext.js
@@ -86,15 +86,14 @@ Given('the property {string} has been deleted in web config file', function(key)
return fs.writeFileSync(this.fullPathOfConfigFile, JSON.stringify(data, null, 4))
})
-Then('the success/error message with header {string} should be displayed on the webUI', function(
- message
-) {
- return client.page
- .webPage()
- .waitForElementVisible('@message')
- .expect.element('@message')
- .text.to.equal(message)
-})
+Then(
+ 'the success/error message with header {string} should be displayed on the webUI',
+ async function(message) {
+ const text = await client.page.webPage().getDisplayedMessage(true)
+ assert.strictEqual(text, message)
+ return await client.page.webPage().waitForElementNotPresent('@message')
+ }
+)
Then('the following success/error message should be displayed on the webUI', async function(
message
diff --git a/tests/acceptance/stepDefinitions/privateLinksContext.js b/tests/acceptance/stepDefinitions/privateLinksContext.js
index cc3eb24e91b..630670a2f8e 100644
--- a/tests/acceptance/stepDefinitions/privateLinksContext.js
+++ b/tests/acceptance/stepDefinitions/privateLinksContext.js
@@ -5,21 +5,20 @@ const webdav = require('../helpers/webdavHelper')
When(
'the user copies the private link of the file/folder/resource {string} using the webUI',
async function(resource) {
- await client.page.FilesPageElement.appSideBar()
- .closeSidebar(100)
- .openPublicLinkDialog(resource)
+ await client.page.FilesPageElement.filesList().openPublicLinkDialog(resource)
return client.page.FilesPageElement.publicLinksDialog().copyPrivateLink()
}
)
-When('the user navigates to the copied private/public link using the webUI', function() {
- return client.getClipBoardContent(function(url) {
- // If the redirect happens immediately we receive an error
- // Cannot read property 'parentNode' of null
- setTimeout(function() {
- client.url(url)
- }, 0)
+When('the user navigates to the copied private/public link using the webUI', async function() {
+ let url
+ await client.getClipBoardContent(u => {
+ url = u
})
+ return await client
+ .url(url)
+ .page.FilesPageElement.filesList()
+ .waitForElementVisible('@anyAfterLoading')
})
When(
@@ -33,11 +32,15 @@ When(
}
)
+When('the private link resolved successfully', async function() {
+ return await client.page.FilesPageElement.filesList().waitForElementVisible('@anyAfterLoading')
+})
+
When(
- 'the user tries to navigate to the private link created by user {string} for file/folder {string}',
+ 'an anonymous user tries to navigate to the private link created by user {string} for file/folder {string}',
async function(user, resource) {
const item = await webdav.getProperties(resource, user, ['oc:privatelink'])
- await client
+ return await client
.url(item['oc:privatelink'])
.page.webPage()
.waitForElementNotPresent('@webContainer')
diff --git a/tests/acceptance/stepDefinitions/publicLinkContext.js b/tests/acceptance/stepDefinitions/publicLinkContext.js
index 45fe7d5ad33..bde43c7dec0 100644
--- a/tests/acceptance/stepDefinitions/publicLinkContext.js
+++ b/tests/acceptance/stepDefinitions/publicLinkContext.js
@@ -10,9 +10,7 @@ const loginHelper = require('../helpers/loginHelper')
When(
'the user (tries to )create/creates a new public link for file/folder/resource {string} using the webUI',
async function(resource) {
- await client.page.FilesPageElement.appSideBar()
- .closeSidebar(100)
- .openPublicLinkDialog(resource)
+ await client.page.FilesPageElement.filesList().openPublicLinkDialog(resource)
return client.page.FilesPageElement.publicLinksDialog().addNewLink()
}
)
@@ -21,9 +19,7 @@ When(
'the user (tries to )create/creates a new public link for file/folder/resource {string} using the webUI with',
async function(resource, settingsTable) {
const settings = settingsTable.rowsHash()
- await client.page.FilesPageElement.appSideBar()
- .closeSidebar(100)
- .openPublicLinkDialog(resource)
+ await client.page.FilesPageElement.filesList().openPublicLinkDialog(resource)
return client.page.FilesPageElement.publicLinksDialog().addNewLink(settings)
}
)
@@ -31,9 +27,7 @@ When(
When(
'the user (tries to) create a new public link for file/folder/resource {string} which expires in {string} day/days using the webUI',
async function(resource, days) {
- await client.page.FilesPageElement.appSideBar()
- .closeSidebar(100)
- .openPublicLinkDialog(resource)
+ await client.page.FilesPageElement.filesList().openPublicLinkDialog(resource)
return client.page.FilesPageElement.publicLinksDialog().setPublicLinkDate(days)
}
)
@@ -96,9 +90,7 @@ const loadPublicLinkWithPassword = async function(linkCreator, password, newSess
const editPublicLink = async function(linkName, resource, dataTable) {
const editData = dataTable.rowsHash()
- await client.page.FilesPageElement.appSideBar()
- .closeSidebar(100)
- .openPublicLinkDialog(resource)
+ await client.page.FilesPageElement.filesList().openPublicLinkDialog(resource)
await client.page.FilesPageElement.publicLinksDialog().editPublicLink(linkName, editData)
return client.page.FilesPageElement.publicLinksDialog().savePublicLink()
}
@@ -161,9 +153,7 @@ When(
'the user edits the public link named {string} of file/folder/resource {string} changing following but not saving',
async function(linkName, resource, dataTable) {
const editData = dataTable.rowsHash()
- await client.page.FilesPageElement.appSideBar()
- .closeSidebar(100)
- .openPublicLinkDialog(resource)
+ await client.page.FilesPageElement.filesList().openPublicLinkDialog(resource)
return client.page.FilesPageElement.publicLinksDialog().editPublicLink(linkName, editData)
}
)
@@ -199,10 +189,7 @@ When(
'the user tries to edit expiration of the public link named {string} of file {string} to past date {string}',
async function(linkName, resource, pastDate) {
const api = client.page.FilesPageElement
- await api
- .appSideBar()
- .closeSidebar(100)
- .openPublicLinkDialog(resource)
+ await api.filesList().openPublicLinkDialog(resource)
await api.publicLinksDialog().clickLinkEditBtn(linkName)
const value = sharingHelper.calculateDate(pastDate)
const dateToSet = new Date(Date.parse(value))
@@ -217,9 +204,7 @@ When(
When(
'the user removes the public link named {string} of file/folder/resource {string} using the webUI',
async function(linkName, resource) {
- await client.page.FilesPageElement.appSideBar()
- .closeSidebar(100)
- .openPublicLinkDialog(resource)
+ await client.page.FilesPageElement.filesList().openPublicLinkDialog(resource)
return client.page.FilesPageElement.publicLinksDialog().removePublicLink(linkName)
}
)
@@ -227,9 +212,7 @@ When(
When(
'the user cancels remove the public link named {string} of file/folder/resource {string} using the webUI',
async function(linkName, resource) {
- await client.page.FilesPageElement.appSideBar()
- .closeSidebar(100)
- .openPublicLinkDialog(resource)
+ await client.page.FilesPageElement.filesList().openPublicLinkDialog(resource)
return client.page.FilesPageElement.publicLinksDialog().cancelRemovePublicLink(linkName)
}
)
@@ -248,9 +231,7 @@ Then(
)
async function findMatchingPublicLinkByName(name, role, resource, via = null) {
- await client.page.FilesPageElement.appSideBar()
- .closeSidebar(100)
- .openPublicLinkDialog(resource)
+ await client.page.FilesPageElement.filesList().openPublicLinkDialog(resource)
const shares = await client.page.FilesPageElement.publicLinksDialog().getPublicLinkList()
@@ -291,16 +272,10 @@ Then(
}
)
-When('the user closes the public link details sidebar', function() {
- return client.page.FilesPageElement.appSideBar().closeSidebar(100)
-})
-
When(
'the user copies the url of public link named {string} of file/folder/resource {string} using the webUI',
async function(linkName, resource) {
- await client.page.FilesPageElement.appSideBar()
- .closeSidebar(100)
- .openPublicLinkDialog(resource)
+ await client.page.FilesPageElement.filesList().openPublicLinkDialog(resource)
return client.page.FilesPageElement.publicLinksDialog().copyPublicLinkURI(linkName)
}
)
@@ -315,9 +290,7 @@ Then(
'a public link with the last created link share token as name should be listed for resource {string} on the webUI',
async function(resource) {
const lastShare = await sharingHelper.fetchLastPublicLinkShare(client.globals.currentUser)
- await client.page.FilesPageElement.appSideBar()
- .closeSidebar(100)
- .openPublicLinkDialog(resource)
+ await client.page.FilesPageElement.filesList().openPublicLinkDialog(resource)
const shares = await client.page.FilesPageElement.publicLinksDialog().getPublicLinkList()
const share = shares.find(link => link.name === lastShare.token)
return assert.ok(share.name.length > 0)
diff --git a/tests/acceptance/stepDefinitions/sharingContext.js b/tests/acceptance/stepDefinitions/sharingContext.js
index ed03ace431b..58a3eb0ea89 100644
--- a/tests/acceptance/stepDefinitions/sharingContext.js
+++ b/tests/acceptance/stepDefinitions/sharingContext.js
@@ -41,8 +41,6 @@ const userSharesFileOrFolderWithUserOrGroup = async function(
await api.filesList().openSharingDialog(file)
}
- await api.sharingDialog().waitForAnimationToFinish()
-
return api
.sharingDialog()
.shareWithUserOrGroup(sharee, shareWithGroup, role, permissions, remote, null)
@@ -599,8 +597,8 @@ When('the user cancels the share creation dialog on the webUI', function() {
return client.page.FilesPageElement.sharingDialog().clickCancel()
})
-When('the user types {string} in the share-with-field', function(input) {
- return client.page.FilesPageElement.sharingDialog().enterAutoComplete(input)
+When('the user types {string} in the share-with-field', async function(input) {
+ return await client.page.FilesPageElement.sharingDialog().enterAutoComplete(input)
})
When(
@@ -690,9 +688,9 @@ Then('it should not be possible to share file/folder {string} using the webUI',
const state = await filesList.isSharingButtonPresent(resource)
assert.ok(!state, `Error: Sharing button for resource ${resource} is not in disabled state`)
await filesList.openSideBar(resource)
- const linkItemState = await appSideBar.isLinksPanelSelectPresent()
+ const linkItemState = await appSideBar.isLinksPanelSelectable()
assert.ok(!linkItemState, `Error: Sidebar 'Links' panel for resource ${resource} is present`)
- const collaboratorsItemState = await appSideBar.isCollaboratorsAccordionItemPresent()
+ const collaboratorsItemState = await appSideBar.isSharingPanelSelectable()
assert.ok(
!collaboratorsItemState,
`Error: Sidebar 'People' panel for resource ${resource} is present`
@@ -953,7 +951,7 @@ Then('user {string} should be listed as {string} in the collaborators list on th
Then(
'the share {string} shared with user {string} should have no expiration information displayed on the webUI',
async function(item, user) {
- await client.page.FilesPageElement.filesList().clickRow(item)
+ await client.page.FilesPageElement.filesList().openSideBar(item)
await client.page.FilesPageElement.appSideBar().activatePanel('people')
const elementID = await client.page.FilesPageElement.SharingDialog.collaboratorsDialog().getCollaboratorExpirationInfo(
user
@@ -969,7 +967,7 @@ Then(
Then(
'the expiration information displayed on the webUI of share {string} shared with user {string} should be {string} or {string}',
async function(item, user, information1, information2) {
- await client.page.FilesPageElement.filesList().clickRow(item)
+ await client.page.FilesPageElement.filesList().openSideBar(item)
await client.page.FilesPageElement.appSideBar().activatePanel('people')
const actualInfo = await client.page.FilesPageElement.SharingDialog.collaboratorsDialog().getCollaboratorExpirationInfo(
user
diff --git a/yarn.lock b/yarn.lock
index efad515ca81..8f25026d5b4 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -8244,10 +8244,10 @@ ospec@3.1.0:
dependencies:
glob "^7.1.3"
-owncloud-design-system@^9.2.0:
- version "9.2.0"
- resolved "https://registry.yarnpkg.com/owncloud-design-system/-/owncloud-design-system-9.2.0.tgz#1e1dfe2fd7bdafe2e80fcebadf841877b908420d"
- integrity sha512-EcDoe3NvX112wk9q+JUIOUDjRrvBXVs16w+ZBv1+fq+9LbXqWbgUTPkkFqKZRNWEN/wbgyDFqoczunQHTIa8jA==
+owncloud-design-system@^9.3.0:
+ version "9.3.0"
+ resolved "https://registry.yarnpkg.com/owncloud-design-system/-/owncloud-design-system-9.3.0.tgz#d27b7562ca7548074a4bcf4ed3128e92a248a8a1"
+ integrity sha512-wOQAd6XXRmNq7+9NNP2m6TKJKt7Xx4hzeghAbeu+7YPCmNHlay7B4IhEpuCt0N+WxPqGg3NiTZQ42PUF4vKM1g==
owncloud-sdk@1.0.0-2296:
version "1.0.0-2296"