Merge pull request #12701 from nextcloud/stable14-12632-add-acceptance-tests-for-sharing-files-and-folders-with-another-user

[stable14] Add acceptance tests for sharing files and folders with another user
This commit is contained in:
Daniel Kesselberg 2018-11-28 14:11:55 +01:00 committed by GitHub
commit e1739e3da9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 802 additions and 291 deletions

View File

@ -678,6 +678,20 @@ pipeline:
when: when:
matrix: matrix:
TESTS-ACCEPTANCE: app-files TESTS-ACCEPTANCE: app-files
acceptance-app-files-sharing:
image: nextcloudci/acceptance-php7.1:acceptance-php7.1-2
commands:
- tests/acceptance/run-local.sh --timeout-multiplier 10 --nextcloud-server-domain acceptance-app-files-sharing --selenium-server selenium:4444 allow-git-repository-modifications features/app-files-sharing.feature
when:
matrix:
TESTS-ACCEPTANCE: app-files-sharing
acceptance-app-files-sharing-link:
image: nextcloudci/acceptance-php7.1:acceptance-php7.1-2
commands:
- tests/acceptance/run-local.sh --timeout-multiplier 10 --nextcloud-server-domain acceptance-app-files-sharing-link --selenium-server selenium:4444 allow-git-repository-modifications features/app-files-sharing-link.feature
when:
matrix:
TESTS-ACCEPTANCE: app-files-sharing-link
acceptance-app-files-tags: acceptance-app-files-tags:
image: nextcloudci/acceptance-php7.1:acceptance-php7.1-2 image: nextcloudci/acceptance-php7.1:acceptance-php7.1-2
commands: commands:
@ -928,6 +942,10 @@ matrix:
TESTS-ACCEPTANCE: app-comments TESTS-ACCEPTANCE: app-comments
- TESTS: acceptance - TESTS: acceptance
TESTS-ACCEPTANCE: app-files TESTS-ACCEPTANCE: app-files
- TESTS: acceptance
TESTS-ACCEPTANCE: app-files-sharing
- TESTS: acceptance
TESTS-ACCEPTANCE: app-files-sharing-link
- TESTS: acceptance - TESTS: acceptance
TESTS-ACCEPTANCE: app-files-tags TESTS-ACCEPTANCE: app-files-tags
- TESTS: acceptance - TESTS: acceptance

View File

@ -16,9 +16,10 @@ default:
- FeatureContext - FeatureContext
- FileListContext - FileListContext
- FilesAppContext - FilesAppContext
- FilesSharingAppContext - FilesAppSharingContext
- LoginPageContext - LoginPageContext
- NotificationContext - NotificationContext
- PublicShareContext
- SettingsContext - SettingsContext
- SettingsMenuContext - SettingsMenuContext
- ThemingAppContext - ThemingAppContext
@ -42,9 +43,10 @@ default:
- FeatureContext - FeatureContext
- FileListContext - FileListContext
- FilesAppContext - FilesAppContext
- FilesSharingAppContext - FilesAppSharingContext
- LoginPageContext - LoginPageContext
- NotificationContext - NotificationContext
- PublicShareContext
- SettingsContext - SettingsContext
- SettingsMenuContext - SettingsMenuContext
- ThemingAppContext - ThemingAppContext
@ -63,6 +65,9 @@ default:
Jane: Jane:
selenium2: selenium2:
wd_host: %selenium.server% wd_host: %selenium.server%
Jim:
selenium2:
wd_host: %selenium.server%
Rubeus: Rubeus:
# Rubeus uses a browser that has CSS grid support. # Rubeus uses a browser that has CSS grid support.
selenium2: selenium2:

View File

@ -0,0 +1,119 @@
Feature: app-files-sharing-link
Scenario: open the menu in a public shared link
Given I act as John
And I am logged in
And I share the link for "welcome.txt"
And I write down the shared link
When I act as Jane
And I visit the shared link I wrote down
And I see that the current page is the shared link I wrote down
And I open the Share menu
Then I see that the Share menu is shown
Scenario: creation is not possible by default in a public shared folder
Given I act as John
And I am logged in
And I create a new folder named "Shared folder"
# To share the link the "Share" inline action has to be clicked but, as the
# details view is opened automatically when the folder is created, clicking
# on the inline action could fail if it is covered by the details view due
# to its opening animation. Instead of ensuring that the animations of the
# contents and the details view have both finished it is easier to close the
# details view and wait until it is closed before continuing.
And I close the details view
And I see that the details view is closed
And I share the link for "Shared folder"
And I write down the shared link
When I act as Jane
And I visit the shared link I wrote down
And I see that the current page is the shared link I wrote down
And I see that the file list is eventually loaded
Then I see that it is not possible to create new files
Scenario: create folder in a public editable shared folder
Given I act as John
And I am logged in
And I create a new folder named "Editable shared folder"
# To share the link the "Share" inline action has to be clicked but, as the
# details view is opened automatically when the folder is created, clicking
# on the inline action could fail if it is covered by the details view due
# to its opening animation. Instead of ensuring that the animations of the
# contents and the details view have both finished it is easier to close the
# details view and wait until it is closed before continuing.
And I close the details view
And I see that the details view is closed
And I share the link for "Editable shared folder"
And I set the shared link as editable
And I write down the shared link
When I act as Jane
And I visit the shared link I wrote down
And I see that the current page is the shared link I wrote down
And I create a new folder named "Subfolder"
Then I see that the file list contains a file named "Subfolder"
Scenario: owner sees folder created in the public page of an editable shared folder
Given I act as John
And I am logged in
And I create a new folder named "Editable shared folder"
# To share the link the "Share" inline action has to be clicked but, as the
# details view is opened automatically when the folder is created, clicking
# on the inline action could fail if it is covered by the details view due
# to its opening animation. Instead of ensuring that the animations of the
# contents and the details view have both finished it is easier to close the
# details view and wait until it is closed before continuing.
And I close the details view
And I see that the details view is closed
And I share the link for "Editable shared folder"
And I set the shared link as editable
And I write down the shared link
And I act as Jane
And I visit the shared link I wrote down
And I see that the current page is the shared link I wrote down
And I create a new folder named "Subfolder"
And I see that the file list contains a file named "Subfolder"
When I act as John
And I enter in the folder named "Editable shared folder"
Then I see that the file list contains a file named "Subfolder"
Scenario: set a password to a shared link
Given I am logged in
And I share the link for "welcome.txt"
When I protect the shared link with the password "abcdef"
Then I see that the working icon for password protect is shown
And I see that the working icon for password protect is eventually not shown
Scenario: access a shared link protected by password with a valid password
Given I act as John
And I am logged in
And I share the link for "welcome.txt" protected by the password "abcdef"
And I write down the shared link
When I act as Jane
And I visit the shared link I wrote down
And I see that the current page is the Authenticate page for the shared link I wrote down
And I authenticate with password "abcdef"
Then I see that the current page is the shared link I wrote down
And I see that the shared file preview shows the text "Welcome to your Nextcloud account!"
Scenario: access a shared link protected by password with an invalid password
Given I act as John
And I am logged in
And I share the link for "welcome.txt" protected by the password "abcdef"
And I write down the shared link
When I act as Jane
And I visit the shared link I wrote down
And I authenticate with password "fedcba"
Then I see that the current page is the Authenticate page for the shared link I wrote down
And I see that a wrong password for the shared file message is shown
Scenario: access a direct download shared link protected by password with a valid password
Given I act as John
And I am logged in
And I share the link for "welcome.txt" protected by the password "abcdef"
And I write down the shared link
When I act as Jane
And I visit the direct download shared link I wrote down
And I see that the current page is the Authenticate page for the direct download shared link I wrote down
And I authenticate with password "abcdef"
# download starts no page redirection
And I see that the current page is the Authenticate page for the direct download shared link I wrote down

View File

@ -0,0 +1,269 @@
Feature: app-files-sharing
Scenario: share a file with another user
Given I act as John
And I am logged in as the admin
And I act as Jane
And I am logged in
And I act as John
And I rename "welcome.txt" to "farewell.txt"
And I see that the file list contains a file named "farewell.txt"
When I share "farewell.txt" with "user0"
And I see that the file is shared with "user0"
And I act as Jane
# The Files app is open again to reload the file list
And I open the Files app
Then I see that the file list contains a file named "farewell.txt"
And I open the details view for "farewell.txt"
And I see that the details view is open
And I open the "Sharing" tab in the details view
And I see that the "Sharing" tab in the details view is eventually loaded
And I see that the file is shared with me by "admin"
Scenario: share a file with another user who already has a file with that name
Given I act as John
And I am logged in as the admin
And I act as Jane
And I am logged in
And I act as John
When I share "welcome.txt" with "user0"
And I see that the file is shared with "user0"
And I act as Jane
# The Files app is open again to reload the file list
And I open the Files app
Then I see that the file list contains a file named "welcome (2).txt"
And I open the details view for "welcome (2).txt"
And I see that the details view is open
And I open the "Sharing" tab in the details view
And I see that the "Sharing" tab in the details view is eventually loaded
And I see that the file is shared with me by "admin"
Scenario: share a skeleton file with another user before first login
# If a file is shared with a user before her first login the skeleton would
# not have been created, so if the shared file has the same name as one from
# the skeleton the shared file will take its place and the skeleton file
# will not be added.
Given I act as John
And I am logged in as the admin
When I share "welcome.txt" with "user0"
And I see that the file is shared with "user0"
And I act as Jane
And I am logged in
Then I see that the file list contains a file named "welcome.txt"
And I open the details view for "welcome.txt"
And I see that the details view is open
And I open the "Sharing" tab in the details view
And I see that the "Sharing" tab in the details view is eventually loaded
And I see that the file is shared with me by "admin"
Scenario: reshare a file with another user
Given I act as John
And I am logged in as the admin
And I act as Jane
And I am logged in
And I act as Jim
And I am logged in as "user1"
And I act as John
And I rename "welcome.txt" to "farewell.txt"
And I see that the file list contains a file named "farewell.txt"
And I share "farewell.txt" with "user0"
And I see that the file is shared with "user0"
And I act as Jane
# The Files app is open again to reload the file list
And I open the Files app
When I share "farewell.txt" with "user1"
And I see that the file is shared with "user1"
And I act as Jim
# The Files app is open again to reload the file list
And I open the Files app
Then I see that the file list contains a file named "farewell.txt"
And I open the details view for "farewell.txt"
And I see that the details view is open
And I open the "Sharing" tab in the details view
And I see that the "Sharing" tab in the details view is eventually loaded
And I see that the file is shared with me by "user0"
Scenario: owner sees reshares with other users
Given I act as John
And I am logged in as the admin
And I act as Jane
And I am logged in
And I act as John
And I rename "welcome.txt" to "farewell.txt"
And I see that the file list contains a file named "farewell.txt"
And I share "farewell.txt" with "user0"
And I see that the file is shared with "user0"
And I act as Jane
# The Files app is open again to reload the file list
And I open the Files app
And I share "farewell.txt" with "user1"
And I see that the file is shared with "user1"
When I act as John
# The Files app is open again to reload the file list and the shares
And I open the Files app
And I open the details view for "farewell.txt"
And I see that the details view is open
And I open the "Sharing" tab in the details view
And I see that the "Sharing" tab in the details view is eventually loaded
Then I see that the file is shared with "user0"
And I see that the file is shared with "user1"
Scenario: share an empty folder with another user
Given I act as John
And I am logged in as the admin
And I act as Jane
And I am logged in
And I act as John
And I create a new folder named "Shared folder"
And I see that the file list contains a file named "Shared folder"
When I share "Shared folder" with "user0"
And I see that the file is shared with "user0"
And I act as Jane
# The Files app is open again to reload the file list
And I open the Files app
Then I see that the file list contains a file named "Shared folder"
And I open the details view for "Shared folder"
And I see that the details view is open
And I open the "Sharing" tab in the details view
And I see that the "Sharing" tab in the details view is eventually loaded
And I see that the file is shared with me by "admin"
Scenario: sharee sees a folder created by the owner in a shared folder
Given I act as John
And I am logged in as the admin
And I act as Jane
And I am logged in
And I act as John
And I create a new folder named "Shared folder"
And I see that the file list contains a file named "Shared folder"
And I share "Shared folder" with "user0"
And I see that the file is shared with "user0"
And I enter in the folder named "Shared folder"
And I create a new folder named "Subfolder"
And I see that the file list contains a file named "Subfolder"
When I act as Jane
# The Files app is open again to reload the file list
And I open the Files app
And I enter in the folder named "Shared folder"
Then I see that the file list contains a file named "Subfolder"
Scenario: owner sees a folder created by the sharee in a shared folder
Given I act as John
And I am logged in as the admin
And I act as Jane
And I am logged in
And I act as John
And I create a new folder named "Shared folder"
And I see that the file list contains a file named "Shared folder"
And I share "Shared folder" with "user0"
And I see that the file is shared with "user0"
And I act as Jane
# The Files app is open again to reload the file list
And I open the Files app
And I enter in the folder named "Shared folder"
And I create a new folder named "Subfolder"
And I see that the file list contains a file named "Subfolder"
When I act as John
And I enter in the folder named "Shared folder"
Then I see that the file list contains a file named "Subfolder"
Scenario: resharee sees a folder created by the owner in a shared folder
Given I act as John
And I am logged in as the admin
And I act as Jane
And I am logged in
And I act as Jim
And I am logged in as "user1"
And I act as John
And I create a new folder named "Shared folder"
And I see that the file list contains a file named "Shared folder"
And I share "Shared folder" with "user0"
And I see that the file is shared with "user0"
And I act as Jane
# The Files app is open again to reload the file list
And I open the Files app
And I share "Shared folder" with "user1"
And I act as John
And I enter in the folder named "Shared folder"
And I create a new folder named "Subfolder"
And I see that the file list contains a file named "Subfolder"
When I act as Jim
# The Files app is open again to reload the file list
And I open the Files app
And I enter in the folder named "Shared folder"
Then I see that the file list contains a file named "Subfolder"
Scenario: owner sees a folder created by the resharee in a shared folder
Given I act as John
And I am logged in as the admin
And I act as Jane
And I am logged in
And I act as Jim
And I am logged in as "user1"
And I act as John
And I create a new folder named "Shared folder"
And I see that the file list contains a file named "Shared folder"
And I share "Shared folder" with "user0"
And I see that the file is shared with "user0"
And I act as Jane
# The Files app is open again to reload the file list
And I open the Files app
And I share "Shared folder" with "user1"
And I act as Jim
# The Files app is open again to reload the file list
And I open the Files app
And I enter in the folder named "Shared folder"
And I create a new folder named "Subfolder"
And I see that the file list contains a file named "Subfolder"
When I act as John
And I enter in the folder named "Shared folder"
Then I see that the file list contains a file named "Subfolder"
Scenario: sharee can not reshare a folder if the sharer disables it
Given I act as John
And I am logged in as the admin
And I act as Jane
And I am logged in
And I act as John
And I create a new folder named "Shared folder"
And I see that the file list contains a file named "Shared folder"
And I share "Shared folder" with "user0"
And I see that the file is shared with "user0"
And I set the share with "user0" as not reshareable
And I see that "user0" can not reshare the share
When I act as Jane
# The Files app is open again to reload the file list
And I open the Files app
Then I see that the file list contains a file named "Shared folder"
And I open the details view for "Shared folder"
And I see that the details view is open
And I open the "Sharing" tab in the details view
And I see that the "Sharing" tab in the details view is eventually loaded
And I see that the file is shared with me by "admin"
And I see that resharing the file is not allowed
Scenario: sharee can not reshare a subfolder if the sharer disables it for the parent folder
Given I act as John
And I am logged in as the admin
And I act as Jane
And I am logged in
And I act as John
And I create a new folder named "Shared folder"
And I see that the file list contains a file named "Shared folder"
And I share "Shared folder" with "user0"
And I see that the file is shared with "user0"
And I set the share with "user0" as not reshareable
And I see that "user0" can not reshare the share
And I enter in the folder named "Shared folder"
And I create a new folder named "Subfolder"
And I see that the file list contains a file named "Subfolder"
When I act as Jane
# The Files app is open again to reload the file list
And I open the Files app
And I enter in the folder named "Shared folder"
Then I see that the file list contains a file named "Subfolder"
And I open the details view for "Subfolder"
And I see that the details view is open
And I open the "Sharing" tab in the details view
And I see that the "Sharing" tab in the details view is eventually loaded
And I see that resharing the file is not allowed

View File

@ -147,124 +147,6 @@ Feature: app-files
Then I see that the file list contains a file named "farewell.txt" Then I see that the file list contains a file named "farewell.txt"
And I see that the file name shown in the details view is "farewell.txt" And I see that the file name shown in the details view is "farewell.txt"
Scenario: open the menu in a public shared link
Given I act as John
And I am logged in
And I share the link for "welcome.txt"
And I write down the shared link
When I act as Jane
And I visit the shared link I wrote down
And I see that the current page is the shared link I wrote down
And I open the Share menu
Then I see that the Share menu is shown
Scenario: creation is not possible by default in a public shared folder
Given I act as John
And I am logged in
And I create a new folder named "Shared folder"
# To share the link the "Share" inline action has to be clicked but, as the
# details view is opened automatically when the folder is created, clicking
# on the inline action could fail if it is covered by the details view due
# to its opening animation. Instead of ensuring that the animations of the
# contents and the details view have both finished it is easier to close the
# details view and wait until it is closed before continuing.
And I close the details view
And I see that the details view is closed
And I share the link for "Shared folder"
And I write down the shared link
When I act as Jane
And I visit the shared link I wrote down
And I see that the current page is the shared link I wrote down
And I see that the file list is eventually loaded
Then I see that it is not possible to create new files
Scenario: create folder in a public editable shared folder
Given I act as John
And I am logged in
And I create a new folder named "Editable shared folder"
# To share the link the "Share" inline action has to be clicked but, as the
# details view is opened automatically when the folder is created, clicking
# on the inline action could fail if it is covered by the details view due
# to its opening animation. Instead of ensuring that the animations of the
# contents and the details view have both finished it is easier to close the
# details view and wait until it is closed before continuing.
And I close the details view
And I see that the details view is closed
And I share the link for "Editable shared folder"
And I set the shared link as editable
And I write down the shared link
When I act as Jane
And I visit the shared link I wrote down
And I see that the current page is the shared link I wrote down
And I create a new folder named "Subfolder"
Then I see that the file list contains a file named "Subfolder"
Scenario: owner sees folder created in the public page of an editable shared folder
Given I act as John
And I am logged in
And I create a new folder named "Editable shared folder"
# To share the link the "Share" inline action has to be clicked but, as the
# details view is opened automatically when the folder is created, clicking
# on the inline action could fail if it is covered by the details view due
# to its opening animation. Instead of ensuring that the animations of the
# contents and the details view have both finished it is easier to close the
# details view and wait until it is closed before continuing.
And I close the details view
And I see that the details view is closed
And I share the link for "Editable shared folder"
And I set the shared link as editable
And I write down the shared link
And I act as Jane
And I visit the shared link I wrote down
And I see that the current page is the shared link I wrote down
And I create a new folder named "Subfolder"
And I see that the file list contains a file named "Subfolder"
When I act as John
And I enter in the folder named "Editable shared folder"
Then I see that the file list contains a file named "Subfolder"
Scenario: set a password to a shared link
Given I am logged in
And I share the link for "welcome.txt"
When I protect the shared link with the password "abcdef"
Then I see that the working icon for password protect is shown
And I see that the working icon for password protect is eventually not shown
Scenario: access a shared link protected by password with a valid password
Given I act as John
And I am logged in
And I share the link for "welcome.txt" protected by the password "abcdef"
And I write down the shared link
When I act as Jane
And I visit the shared link I wrote down
And I see that the current page is the Authenticate page for the shared link I wrote down
And I authenticate with password "abcdef"
Then I see that the current page is the shared link I wrote down
And I see that the shared file preview shows the text "Welcome to your Nextcloud account!"
Scenario: access a shared link protected by password with an invalid password
Given I act as John
And I am logged in
And I share the link for "welcome.txt" protected by the password "abcdef"
And I write down the shared link
When I act as Jane
And I visit the shared link I wrote down
And I authenticate with password "fedcba"
Then I see that the current page is the Authenticate page for the shared link I wrote down
And I see that a wrong password for the shared file message is shown
Scenario: access a direct download shared link protected by password with a valid password
Given I act as John
And I am logged in
And I share the link for "welcome.txt" protected by the password "abcdef"
And I write down the shared link
When I act as Jane
And I visit the direct download shared link I wrote down
And I see that the current page is the Authenticate page for the direct download shared link I wrote down
And I authenticate with password "abcdef"
# download starts no page redirection
And I see that the current page is the Authenticate page for the direct download shared link I wrote down
Scenario: marking a file as favorite causes the file list to be sorted again Scenario: marking a file as favorite causes the file list to be sorted again
Given I am logged in Given I am logged in
And I create a new folder named "A name alphabetically lower than welcome.txt" And I create a new folder named "A name alphabetically lower than welcome.txt"

View File

@ -42,6 +42,23 @@ class FilesAppContext implements Context, ActorAwareInterface {
"Deleted files" => "trashbin" ]; "Deleted files" => "trashbin" ];
} }
/**
* @return Locator
*/
private static function appMenu() {
return Locator::forThe()->id("appmenu")->
describedAs("App menu in header");
}
/**
* @return Locator
*/
public static function filesItemInAppMenu() {
return Locator::forThe()->xpath("/li[@data-id = 'files']")->
descendantOf(self::appMenu())->
describedAs("Files item in app menu in header");
}
/** /**
* @return Locator * @return Locator
*/ */
@ -212,91 +229,10 @@ class FilesAppContext implements Context, ActorAwareInterface {
} }
/** /**
* @return Locator * @Given I open the Files app
*/ */
public static function shareLinkRow() { public function iOpenTheFilesApp() {
return Locator::forThe()->id("shareLink")-> $this->actor->find(self::filesItemInAppMenu(), 10)->click();
descendantOf(self::detailsView())->
describedAs("Share link row in the details view in Files app");
}
/**
* @return Locator
*/
public static function shareLinkCheckbox() {
// forThe()->checkbox("Enable") can not be used here; that would return
// the checkbox itself, but the element that the user interacts with is
// the label.
return Locator::forThe()->xpath("//label[normalize-space() = 'Enable']")->
descendantOf(self::shareLinkRow())->
describedAs("Share link checkbox in the details view in Files app");
}
/**
* @return Locator
*/
public static function shareLinkMenuButton() {
return Locator::forThe()->css(".share-menu > .icon")->
descendantOf(self::shareLinkRow())->
describedAs("Share link menu button in the details view in Files app");
}
/**
* @return Locator
*/
public static function shareLinkMenu() {
return Locator::forThe()->css(".share-menu > .menu")->
descendantOf(self::shareLinkRow())->
describedAs("Share link menu in the details view in Files app");
}
/**
* @return Locator
*/
public static function copyUrlMenuItem() {
return Locator::forThe()->xpath("//a[normalize-space() = 'Copy URL']")->
descendantOf(self::shareLinkMenu())->
describedAs("Copy URL menu item in the share link menu in the details view in Files app");
}
/**
* @return Locator
*/
public static function allowUploadAndEditingRadioButton() {
// forThe()->radio("Allow upload and editing") can not be used here;
// that would return the radio button itself, but the element that the
// user interacts with is the label.
return Locator::forThe()->xpath("//label[normalize-space() = 'Allow upload and editing']")->
descendantOf(self::shareLinkMenu())->
describedAs("Allow upload and editing radio button in the details view in Files app");
}
/**
* @return Locator
*/
public static function passwordProtectCheckbox() {
// forThe()->checkbox("Password protect") can not be used here; that
// would return the checkbox itself, but the element that the user
// interacts with is the label.
return Locator::forThe()->xpath("//label[normalize-space() = 'Password protect']")->
descendantOf(self::shareLinkMenu())->
describedAs("Password protect checkbox in the details view in Files app");
}
/**
* @return Locator
*/
public static function passwordProtectField() {
return Locator::forThe()->css(".linkPassText")->descendantOf(self::shareLinkMenu())->
describedAs("Password protect field in the details view in Files app");
}
/**
* @return Locator
*/
public static function passwordProtectWorkingIcon() {
return Locator::forThe()->css(".linkPassMenu .icon-loading-small")->descendantOf(self::shareLinkMenu())->
describedAs("Password protect working icon in the details view in Files app");
} }
/** /**
@ -320,29 +256,6 @@ class FilesAppContext implements Context, ActorAwareInterface {
$this->actor->find(self::tabHeaderInDetailsViewNamed($tabName), 10)->click(); $this->actor->find(self::tabHeaderInDetailsViewNamed($tabName), 10)->click();
} }
/**
* @Given I share the link for :fileName
*/
public function iShareTheLinkFor($fileName) {
$this->actor->find(FileListContext::shareActionForFile(self::currentSectionMainView(), $fileName), 10)->click();
$this->actor->find(self::shareLinkCheckbox(), 5)->click();
}
/**
* @Given I write down the shared link
*/
public function iWriteDownTheSharedLink() {
$this->showShareLinkMenuIfNeeded();
$this->actor->find(self::copyUrlMenuItem(), 2)->click();
// Clicking on the menu item copies the link to the clipboard, but it is
// not possible to access that value from the acceptance tests. Due to
// this the value of the attribute that holds the URL is used instead.
$this->actor->getSharedNotebook()["shared link"] = $this->actor->find(self::copyUrlMenuItem(), 2)->getWrappedElement()->getAttribute("data-clipboard-text");
}
/** /**
* @When I mark the file as favorite in the details view * @When I mark the file as favorite in the details view
*/ */
@ -379,26 +292,6 @@ class FilesAppContext implements Context, ActorAwareInterface {
$this->actor->find(self::itemInDropdownForTag($tag), 10)->click(); $this->actor->find(self::itemInDropdownForTag($tag), 10)->click();
} }
/**
* @When I set the shared link as editable
*/
public function iSetTheSharedLinkAsEditable() {
$this->showShareLinkMenuIfNeeded();
$this->actor->find(self::allowUploadAndEditingRadioButton(), 2)->click();
}
/**
* @When I protect the shared link with the password :password
*/
public function iProtectTheSharedLinkWithThePassword($password) {
$this->showShareLinkMenuIfNeeded();
$this->actor->find(self::passwordProtectCheckbox(), 2)->click();
$this->actor->find(self::passwordProtectField(), 2)->setValue($password . "\r");
}
/** /**
* @Then I see that the current page is the Files app * @Then I see that the current page is the Files app
*/ */
@ -520,47 +413,4 @@ class FilesAppContext implements Context, ActorAwareInterface {
PHPUnit_Framework_Assert::fail("The $tabName tab in the details view has not been loaded after $timeout seconds"); PHPUnit_Framework_Assert::fail("The $tabName tab in the details view has not been loaded after $timeout seconds");
} }
} }
/**
* @Then I see that the working icon for password protect is shown
*/
public function iSeeThatTheWorkingIconForPasswordProtectIsShown() {
PHPUnit_Framework_Assert::assertNotNull($this->actor->find(self::passwordProtectWorkingIcon(), 10));
}
/**
* @Then I see that the working icon for password protect is eventually not shown
*/
public function iSeeThatTheWorkingIconForPasswordProtectIsEventuallyNotShown() {
if (!WaitFor::elementToBeEventuallyNotShown(
$this->actor,
self::passwordProtectWorkingIcon(),
$timeout = 10 * $this->actor->getFindTimeoutMultiplier())) {
PHPUnit_Framework_Assert::fail("The working icon for password protect is still shown after $timeout seconds");
}
}
/**
* @Given I share the link for :fileName protected by the password :password
*/
public function iShareTheLinkForProtectedByThePassword($fileName, $password) {
$this->iShareTheLinkFor($fileName);
$this->iProtectTheSharedLinkWithThePassword($password);
$this->iSeeThatTheWorkingIconForPasswordProtectIsShown();
$this->iSeeThatTheWorkingIconForPasswordProtectIsEventuallyNotShown();
}
private function showShareLinkMenuIfNeeded() {
// In some cases the share menu is hidden after clicking on an action of
// the menu. Therefore, if the menu is visible, wait a little just in
// case it is in the process of being hidden due to a previous action,
// in which case it is shown again.
if (WaitFor::elementToBeEventuallyNotShown(
$this->actor,
self::shareLinkMenu(),
$timeout = 2 * $this->actor->getFindTimeoutMultiplier())) {
$this->actor->find(self::shareLinkMenuButton(), 10)->click();
}
}
} }

View File

@ -0,0 +1,358 @@
<?php
/**
*
* @copyright Copyright (c) 2018, Daniel Calviño Sánchez (danxuliu@gmail.com)
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
use Behat\Behat\Context\Context;
class FilesAppSharingContext implements Context, ActorAwareInterface {
use ActorAware;
/**
* @return Locator
*/
public static function sharedByLabel() {
return Locator::forThe()->css(".reshare")->
descendantOf(FilesAppContext::detailsView())->
describedAs("Shared by label in the details view in Files app");
}
/**
* @return Locator
*/
public static function shareWithInput() {
return Locator::forThe()->css(".shareWithField")->
descendantOf(FilesAppContext::detailsView())->
describedAs("Share with input in the details view in Files app");
}
/**
* @return Locator
*/
public static function shareeList() {
return Locator::forThe()->css(".shareeListView")->
descendantOf(FilesAppContext::detailsView())->
describedAs("Sharee list in the details view in Files app");
}
/**
* @return Locator
*/
public static function sharedWithRow($sharedWithName) {
// "username" class is used for any type of share, not only for shares
// with users.
return Locator::forThe()->xpath("//span[contains(concat(' ', normalize-space(@class), ' '), ' username ') and normalize-space() = '$sharedWithName']/ancestor::li")->
descendantOf(self::shareeList())->
describedAs("Shared with $sharedWithName row in the details view in Files app");
}
/**
* @return Locator
*/
public static function shareWithMenuButton($sharedWithName) {
return Locator::forThe()->css(".share-menu > .icon")->
descendantOf(self::sharedWithRow($sharedWithName))->
describedAs("Share with $sharedWithName menu button in the details view in Files app");
}
/**
* @return Locator
*/
public static function shareWithMenu($sharedWithName) {
return Locator::forThe()->css(".share-menu > .menu")->
descendantOf(self::sharedWithRow($sharedWithName))->
describedAs("Share with $sharedWithName menu in the details view in Files app");
}
/**
* @return Locator
*/
public static function canReshareCheckbox($sharedWithName) {
// forThe()->checkbox("Can reshare") can not be used here; that would
// return the checkbox itself, but the element that the user interacts
// with is the label.
return Locator::forThe()->xpath("//label[normalize-space() = 'Can reshare']")->
descendantOf(self::shareWithMenu($sharedWithName))->
describedAs("Can reshare checkbox in the share with $sharedWithName menu in the details view in Files app");
}
/**
* @return Locator
*/
public static function canReshareCheckboxInput($sharedWithName) {
return Locator::forThe()->checkbox("Can reshare")->
descendantOf(self::shareWithMenu($sharedWithName))->
describedAs("Can reshare checkbox input in the share with $sharedWithName menu in the details view in Files app");
}
/**
* @return Locator
*/
public static function shareLinkRow() {
return Locator::forThe()->id("shareLink")->
descendantOf(FilesAppContext::detailsView())->
describedAs("Share link row in the details view in Files app");
}
/**
* @return Locator
*/
public static function shareLinkCheckbox() {
// forThe()->checkbox("Enable") can not be used here; that would return
// the checkbox itself, but the element that the user interacts with is
// the label.
return Locator::forThe()->xpath("//label[normalize-space() = 'Enable']")->
descendantOf(self::shareLinkRow())->
describedAs("Share link checkbox in the details view in Files app");
}
/**
* @return Locator
*/
public static function shareLinkMenuButton() {
return Locator::forThe()->css(".share-menu > .icon")->
descendantOf(self::shareLinkRow())->
describedAs("Share link menu button in the details view in Files app");
}
/**
* @return Locator
*/
public static function shareLinkMenu() {
return Locator::forThe()->css(".share-menu > .menu")->
descendantOf(self::shareLinkRow())->
describedAs("Share link menu in the details view in Files app");
}
/**
* @return Locator
*/
public static function copyUrlMenuItem() {
return Locator::forThe()->xpath("//a[normalize-space() = 'Copy URL']")->
descendantOf(self::shareLinkMenu())->
describedAs("Copy URL menu item in the share link menu in the details view in Files app");
}
/**
* @return Locator
*/
public static function allowUploadAndEditingRadioButton() {
// forThe()->radio("Allow upload and editing") can not be used here;
// that would return the radio button itself, but the element that the
// user interacts with is the label.
return Locator::forThe()->xpath("//label[normalize-space() = 'Allow upload and editing']")->
descendantOf(self::shareLinkMenu())->
describedAs("Allow upload and editing radio button in the details view in Files app");
}
/**
* @return Locator
*/
public static function passwordProtectCheckbox() {
// forThe()->checkbox("Password protect") can not be used here; that
// would return the checkbox itself, but the element that the user
// interacts with is the label.
return Locator::forThe()->xpath("//label[normalize-space() = 'Password protect']")->
descendantOf(self::shareLinkMenu())->
describedAs("Password protect checkbox in the details view in Files app");
}
/**
* @return Locator
*/
public static function passwordProtectField() {
return Locator::forThe()->css(".linkPassText")->descendantOf(self::shareLinkMenu())->
describedAs("Password protect field in the details view in Files app");
}
/**
* @return Locator
*/
public static function passwordProtectWorkingIcon() {
return Locator::forThe()->css(".linkPassMenu .icon-loading-small")->descendantOf(self::shareLinkMenu())->
describedAs("Password protect working icon in the details view in Files app");
}
/**
* @Given I share the link for :fileName
*/
public function iShareTheLinkFor($fileName) {
$this->actor->find(FileListContext::shareActionForFile(FilesAppContext::currentSectionMainView(), $fileName), 10)->click();
$this->actor->find(self::shareLinkCheckbox(), 5)->click();
}
/**
* @Given I share :fileName with :shareWithName
*/
public function iShareWith($fileName, $shareWithName) {
$this->actor->find(FileListContext::shareActionForFile(FilesAppContext::currentSectionMainView(), $fileName), 10)->click();
$this->actor->find(self::shareWithInput(), 5)->setValue($shareWithName . "\r");
}
/**
* @Given I write down the shared link
*/
public function iWriteDownTheSharedLink() {
$this->showShareLinkMenuIfNeeded();
$this->actor->find(self::copyUrlMenuItem(), 2)->click();
// Clicking on the menu item copies the link to the clipboard, but it is
// not possible to access that value from the acceptance tests. Due to
// this the value of the attribute that holds the URL is used instead.
$this->actor->getSharedNotebook()["shared link"] = $this->actor->find(self::copyUrlMenuItem(), 2)->getWrappedElement()->getAttribute("data-clipboard-text");
}
/**
* @When I set the shared link as editable
*/
public function iSetTheSharedLinkAsEditable() {
$this->showShareLinkMenuIfNeeded();
$this->actor->find(self::allowUploadAndEditingRadioButton(), 2)->click();
}
/**
* @When I protect the shared link with the password :password
*/
public function iProtectTheSharedLinkWithThePassword($password) {
$this->showShareLinkMenuIfNeeded();
$this->actor->find(self::passwordProtectCheckbox(), 2)->click();
$this->actor->find(self::passwordProtectField(), 2)->setValue($password . "\r");
}
/**
* @When I set the share with :shareWithName as not reshareable
*/
public function iSetTheShareWithAsNotReshareable($shareWithName) {
$this->showShareWithMenuIfNeeded($shareWithName);
$this->iSeeThatCanReshareTheShare($shareWithName);
$this->actor->find(self::canReshareCheckbox($shareWithName), 2)->click();
}
/**
* @Then I see that the file is shared with me by :sharedByName
*/
public function iSeeThatTheFileIsSharedWithMeBy($sharedByName) {
PHPUnit_Framework_Assert::assertEquals(
$this->actor->find(self::sharedByLabel(), 10)->getText(), "Shared with you by $sharedByName");
}
/**
* @Then I see that the file is shared with :sharedWithName
*/
public function iSeeThatTheFileIsSharedWith($sharedWithName) {
PHPUnit_Framework_Assert::assertTrue(
$this->actor->find(self::sharedWithRow($sharedWithName), 10)->isVisible());
}
/**
* @Then I see that resharing the file is not allowed
*/
public function iSeeThatResharingTheFileIsNotAllowed() {
PHPUnit_Framework_Assert::assertEquals(
$this->actor->find(self::shareWithInput(), 10)->getWrappedElement()->getAttribute("disabled"), "disabled");
PHPUnit_Framework_Assert::assertEquals(
$this->actor->find(self::shareWithInput(), 10)->getWrappedElement()->getAttribute("placeholder"), "Resharing is not allowed");
}
/**
* @Then I see that :sharedWithName can reshare the share
*/
public function iSeeThatCanReshareTheShare($sharedWithName) {
$this->showShareWithMenuIfNeeded($sharedWithName);
PHPUnit_Framework_Assert::assertTrue(
$this->actor->find(self::canReshareCheckboxInput($sharedWithName), 10)->isChecked());
}
/**
* @Then I see that :sharedWithName can not reshare the share
*/
public function iSeeThatCanNotReshareTheShare($sharedWithName) {
$this->showShareWithMenuIfNeeded($sharedWithName);
PHPUnit_Framework_Assert::assertFalse(
$this->actor->find(self::canReshareCheckboxInput($sharedWithName), 10)->isChecked());
}
/**
* @Then I see that the working icon for password protect is shown
*/
public function iSeeThatTheWorkingIconForPasswordProtectIsShown() {
PHPUnit_Framework_Assert::assertNotNull($this->actor->find(self::passwordProtectWorkingIcon(), 10));
}
/**
* @Then I see that the working icon for password protect is eventually not shown
*/
public function iSeeThatTheWorkingIconForPasswordProtectIsEventuallyNotShown() {
if (!WaitFor::elementToBeEventuallyNotShown(
$this->actor,
self::passwordProtectWorkingIcon(),
$timeout = 10 * $this->actor->getFindTimeoutMultiplier())) {
PHPUnit_Framework_Assert::fail("The working icon for password protect is still shown after $timeout seconds");
}
}
/**
* @Given I share the link for :fileName protected by the password :password
*/
public function iShareTheLinkForProtectedByThePassword($fileName, $password) {
$this->iShareTheLinkFor($fileName);
$this->iProtectTheSharedLinkWithThePassword($password);
$this->iSeeThatTheWorkingIconForPasswordProtectIsShown();
$this->iSeeThatTheWorkingIconForPasswordProtectIsEventuallyNotShown();
}
private function showShareLinkMenuIfNeeded() {
// In some cases the share menu is hidden after clicking on an action of
// the menu. Therefore, if the menu is visible, wait a little just in
// case it is in the process of being hidden due to a previous action,
// in which case it is shown again.
if (WaitFor::elementToBeEventuallyNotShown(
$this->actor,
self::shareLinkMenu(),
$timeout = 2 * $this->actor->getFindTimeoutMultiplier())) {
$this->actor->find(self::shareLinkMenuButton(), 10)->click();
}
}
private function showShareWithMenuIfNeeded($shareWithName) {
// In some cases the share menu is hidden after clicking on an action of
// the menu. Therefore, if the menu is visible, wait a little just in
// case it is in the process of being hidden due to a previous action,
// in which case it is shown again.
if (WaitFor::elementToBeEventuallyNotShown(
$this->actor,
self::shareWithMenu($shareWithName),
$timeout = 2 * $this->actor->getFindTimeoutMultiplier())) {
$this->actor->find(self::shareWithMenuButton($shareWithName), 10)->click();
}
}
}

View File

@ -131,6 +131,15 @@ class LoginPageContext implements Context, ActorAwareInterface {
$this->filesAppContext->iSeeThatTheCurrentPageIsTheFilesApp(); $this->filesAppContext->iSeeThatTheCurrentPageIsTheFilesApp();
} }
/**
* @Given I am logged in as :userName
*/
public function iAmLoggedInAs($userName) {
$this->featureContext->iVisitTheHomePage();
$this->iLogInWithUserAndPassword($userName, "123456acb");
$this->filesAppContext->iSeeThatTheCurrentPageIsTheFilesApp();
}
/** /**
* @Given I am logged in as the admin * @Given I am logged in as the admin
*/ */

View File

@ -23,7 +23,7 @@
use Behat\Behat\Context\Context; use Behat\Behat\Context\Context;
class FilesSharingAppContext implements Context, ActorAwareInterface { class PublicShareContext implements Context, ActorAwareInterface {
use ActorAware; use ActorAware;
use FileListAncestorSetter; use FileListAncestorSetter;

View File

@ -35,6 +35,7 @@ fi
php occ maintenance:install --admin-pass=admin php occ maintenance:install --admin-pass=admin
OC_PASS=123456acb php occ user:add --password-from-env user0 OC_PASS=123456acb php occ user:add --password-from-env user0
OC_PASS=123456acb php occ user:add --password-from-env user1
OC_PASS=123456acb php occ user:add --password-from-env disabledUser OC_PASS=123456acb php occ user:add --password-from-env disabledUser
php occ user:disable disabledUser php occ user:disable disabledUser