From c32760833574f63b31381deffdb0b43d36b1f49f Mon Sep 17 00:00:00 2001 From: Artur Neumann Date: Mon, 28 Aug 2017 10:24:14 +0545 Subject: [PATCH] UI tests for delete feature --- tests/ui/features/bootstrap/FilesContext.php | 91 +++++++++++++++++-- tests/ui/features/files/delete.feature | 71 +++++++++++++++ tests/ui/features/lib/FilesPage.php | 59 +++++++++++- .../lib/FilesPageElement/FileActionsMenu.php | 3 +- .../features/lib/FilesPageElement/FileRow.php | 31 ++++++- tests/ui/features/lib/OwncloudPage.php | 14 +++ 6 files changed, 253 insertions(+), 16 deletions(-) create mode 100644 tests/ui/features/files/delete.feature diff --git a/tests/ui/features/bootstrap/FilesContext.php b/tests/ui/features/bootstrap/FilesContext.php index ec9db4fed5f7..fa330e5300d3 100644 --- a/tests/ui/features/bootstrap/FilesContext.php +++ b/tests/ui/features/bootstrap/FilesContext.php @@ -24,6 +24,7 @@ use Behat\MinkExtension\Context\RawMinkContext; use Behat\Gherkin\Node\TableNode; use Page\FilesPage; +use SensioLabs\Behat\PageObjectExtension\PageObject\Exception\ElementNotFoundException; require_once 'bootstrap.php'; @@ -135,8 +136,60 @@ public function iRenameTheFileToOneOfThisNames($fromName, TableNode $table) } + /** + * @When I delete the file/folder :name + * @param string $name + * @return void + */ + public function iDeleteTheFile($name) { + $session = $this->getSession(); + $this->filesPage->waitTillPageIsLoaded($session); + $this->filesPage->deleteFile($name, $session); + } + + /** + * @When I delete the following file/folder + * @param TableNode $namePartsTable table of parts of the file name + * table headings: must be: |name-parts | + * @return void + */ + public function iDeleteTheFollowingFile(TableNode $namePartsTable) { + $fileNameParts = []; + + foreach ($namePartsTable as $namePartsRow) { + $fileNameParts[] = $namePartsRow['name-parts']; + } + $this->filesPage->waitTillPageIsLoaded($this->getSession()); + $this->filesPage->deleteFile($fileNameParts, $this->getSession()); + } + + /** + * @When I batch delete the marked files + * @return void + */ + public function iBatchDeleteTheMarkedFiles() { + $this->filesPage->deleteAllSelectedFiles($this->getSession()); + } + + /** + * @When I mark these files for batch action + * @param TableNode $files table of file names + * table headings: must be: |name| + * @return void + */ + public function iMarkTheseFilesForBatchAction(TableNode $files) { + $this->filesPage->waitTillPageIsLoaded($this->getSession()); + foreach ($files as $file) { + $this->filesPage->selectFileForBatchAction( + $file['name'], $this->getSession() + ); + } + } + /** * @Then the file/folder :name should be listed + * @param string $name + * @return void */ public function theFileFolderShouldBeListed($name) { @@ -146,21 +199,47 @@ public function theFileFolderShouldBeListed($name) } /** - * @Then the following file/folder should be listed + * @Then the file/folder :name should not be listed + * @param string $name + * @return void + */ + public function theFileFolderShouldNotBeListed($name) { + $message = null; + try { + $this->filesPage->findFileRowByName($name, $this->getSession()); + } catch (ElementNotFoundException $e) { + $message = $e->getMessage(); + } + if (is_array($name)) { + $name = implode($name); + } + PHPUnit_Framework_Assert::assertEquals( + "could not find file with the name '" . $name . "'", + $message + ); + } + + /** + * @Then /^the following (?:file|folder) should (not|)\s?be listed$/ + * @param string $shouldOrNot * @param TableNode $namePartsTable table of parts of the file name * table headings: must be: |name-parts | */ - public function theFollowingFileFolderShouldBeListed(TableNode $namePartsTable) - { + public function theFollowingFileFolderShouldBeListed( + $shouldOrNot, TableNode $namePartsTable + ) { + $should = ($shouldOrNot !== "not"); $fileNameParts = []; foreach ($namePartsTable as $namePartsRow) { $fileNameParts[] = $namePartsRow['name-parts']; } - PHPUnit_Framework_Assert::assertNotNull( - $this->filesPage->findFileRowByName($fileNameParts, $this->getSession()) - ); + if ($should) { + $this->theFileFolderShouldBeListed($fileNameParts); + } else { + $this->theFileFolderShouldNotBeListed($fileNameParts); + } } /** diff --git a/tests/ui/features/files/delete.feature b/tests/ui/features/files/delete.feature new file mode 100644 index 000000000000..35987598307e --- /dev/null +++ b/tests/ui/features/files/delete.feature @@ -0,0 +1,71 @@ +Feature: delete + + Background: + Given a regular user exists + And I am logged in as a regular user + And I am on the files page + + Scenario: Delete files & folders one by one and check its existence after page reload + When I delete the folder "simple-folder" + Then the folder "simple-folder" should not be listed + When I delete the file "lorem.txt" + Then the file "lorem.txt" should not be listed + When I delete the folder "strängé नेपाली folder" + Then the folder "strängé नेपाली folder" should not be listed + When I delete the file "strängé filename (duplicate #2).txt" + Then the file "strängé filename (duplicate #2).txt" should not be listed + When the files page is reloaded + Then the folder "simple-folder" should not be listed + And the folder "strängé नेपाली folder" should not be listed + And the file "lorem.txt" should not be listed + And the file "strängé filename (duplicate #2).txt" should not be listed + + Scenario: Delete a file with problematic characters + When I rename the following file to + |from-name-parts |to-name-parts | + |lorem.txt |'single' | + | |"double" quotes| + | |question? | + | |&and#hash | + And the files page is reloaded + Then the following file should be listed + |name-parts | + |'single' | + |"double" quotes| + |question? | + |&and#hash | + And I delete the following file + |name-parts | + |'single' | + |"double" quotes| + |question? | + |&and#hash | + Then the following file should not be listed + |name-parts | + |'single' | + |"double" quotes| + |question? | + |&and#hash | + And the files page is reloaded + Then the following file should not be listed + |name-parts | + |'single' | + |"double" quotes| + |question? | + |&and#hash | + + Scenario: Delete multiple files at once + When I mark these files for batch action + |name | + |data.zip| + |lorem.txt| + |simple-folder| + And I batch delete the marked files + Then the folder "simple-folder" should not be listed + And the file "data.zip" should not be listed + And the file "lorem.txt" should not be listed + When the files page is reloaded + Then the folder "simple-folder" should not be listed + And the file "data.zip" should not be listed + And the file "lorem.txt" should not be listed + \ No newline at end of file diff --git a/tests/ui/features/lib/FilesPage.php b/tests/ui/features/lib/FilesPage.php index ec6177d118d1..afdcbef54b1c 100644 --- a/tests/ui/features/lib/FilesPage.php +++ b/tests/ui/features/lib/FilesPage.php @@ -51,6 +51,7 @@ class FilesPage extends OwnCloudPage //TODO make simpler, only ID .//*[@id='fileList'] protected $fileListXpath = ".//div[@id='app-content-files']//tbody[@id='fileList']"; protected $loadingIndicatorXpath = ".//*[@class='loading']"; + protected $deleteAllSelectedBtnXpath = ".//*[@id='app-content-files']//*[@class='delete-selected']"; private $strForNormalFileName = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'; @@ -136,6 +137,7 @@ public function findFileRowByName($name, Session $session) { $previousFileCount = 0; $currentFileCount = null; + $this->scrollToPosition('#' . $this->appContentId, 0, $session); if (is_array($name)) { // Concatenating separate parts of the file name allows @@ -219,10 +221,11 @@ public function closeSharingDialog() { */ public function scrollDownAppContent (Session $session) { - $session->evaluateScript( - '$("#' . $this->appContentId . '").scrollTop($("#' . $this->appContentId . '")[0].scrollHeight);' + $this->scrollToPosition( + '#' . $this->appContentId, + '$("#' . $this->appContentId . '")[0].scrollHeight', + $session ); - $this->waitForOutstandingAjaxCalls($session); } @@ -277,6 +280,55 @@ public function renameFile($fromFileName, $toFileName, Session $session, $maxRet } } + /** + * + * @param string $name + * @param Session $session + * @return void + */ + public function deleteFile($name, Session $session) { + $row = $this->findFileRowByName($name, $session); + $row->delete(); + $this->waitForAjaxCallsToStartAndFinish($session); + } + + /** + * + * @throws ElementNotFoundException + * @return \Behat\Mink\Element\NodeElement + */ + public function findDeleteAllSelectedFilesBtn() { + $deleteAllSelectedBtn = $this->find( + "xpath", $this->deleteAllSelectedBtnXpath + ); + if (is_null($deleteAllSelectedBtn)) { + throw new ElementNotFoundException( + "could not find button to delete all selected files" + ); + } + return $deleteAllSelectedBtn; + } + + /** + * + * @param Session $session + * @return void + */ + public function deleteAllSelectedFiles(Session $session) { + $this->findDeleteAllSelectedFilesBtn()->click(); + $this->waitForAjaxCallsToStartAndFinish($session); + } + + /** + * + * @param string $name + * @param Session $session + * @return void + */ + public function selectFileForBatchAction($name, Session $session) { + $row = $this->findFileRowByName($name, $session); + $row->selectForBatchAction(); + } /** * * @param int $number @@ -298,7 +350,6 @@ public function findFileActionsMenuBtnByNo($number) { * @return void */ public function clickFileActionsMenuBtnByNo($number) { - $this->findFileActionsMenuBtnByNo($number)->click(); } diff --git a/tests/ui/features/lib/FilesPageElement/FileActionsMenu.php b/tests/ui/features/lib/FilesPageElement/FileActionsMenu.php index 74df93c8f746..785357c964ea 100644 --- a/tests/ui/features/lib/FilesPageElement/FileActionsMenu.php +++ b/tests/ui/features/lib/FilesPageElement/FileActionsMenu.php @@ -76,7 +76,8 @@ public function rename( * @return void */ public function delete() { - ; + $deleteBtn = $this->findButton($this->deleteActionLabel); + $deleteBtn->click(); } /** diff --git a/tests/ui/features/lib/FilesPageElement/FileRow.php b/tests/ui/features/lib/FilesPageElement/FileRow.php index e2204c22f416..72633c6870ca 100644 --- a/tests/ui/features/lib/FilesPageElement/FileRow.php +++ b/tests/ui/features/lib/FilesPageElement/FileRow.php @@ -26,6 +26,7 @@ use Page\OwncloudPage; use SensioLabs\Behat\PageObjectExtension\PageObject\Exception\ElementNotFoundException; use Behat\Mink\Element\NodeElement; +use Behat\Mink\Session; /** * Object of a row on the FilesPage @@ -167,7 +168,7 @@ public function findRenameInputField() { */ public function rename($toName) { $actionMenu = $this->openFileActionsMenu(); - $actionMenu->rename($this->fileRenameInputXpath); + $actionMenu->rename(); $this->waitTillElementIsNotNull($this->fileRenameInputXpath); $inputField = $this->findRenameInputField(); $this->cleanInputAndSetValue($inputField, $toName); @@ -175,6 +176,16 @@ public function rename($toName) { $this->waitTillElementIsNull($this->fileBusyIndicatorXpath); } + /** + * deletes the file + * + * @return void + */ + public function delete() { + $actionMenu = $this->openFileActionsMenu(); + $actionMenu->delete(); + } + /** * finds and returns the tooltip element * @@ -191,6 +202,15 @@ public function findTooltipElement() { return $element; } + /** + * returns the tooltip text + * + * @return string + */ + public function getTooltip() { + return $this->findTooltipElement()->getText(); + } + /** * finds and returns the thumbnail of the file * @@ -206,12 +226,13 @@ public function findThumbnail() { } return $thumbnail; } + /** - * returns the tooltip text + * selects this row for batch action e.g. download or delete * - * @return string + * @return void */ - public function getTooltip() { - return $this->findTooltipElement()->getText(); + public function selectForBatchAction() { + $this->findThumbnail()->click(); } } \ No newline at end of file diff --git a/tests/ui/features/lib/OwncloudPage.php b/tests/ui/features/lib/OwncloudPage.php index 01e7b98a17e4..0759785159ae 100644 --- a/tests/ui/features/lib/OwncloudPage.php +++ b/tests/ui/features/lib/OwncloudPage.php @@ -166,6 +166,20 @@ public function getWindowHeight($session) ); } + /** + * scrolls to a position in a specified element + * + * @param string $jQuerySelector e.g. "#app-content" + * @param int|string $position number or JS function that returns a number + * @param Session $session + * @return void + */ + public function scrollToPosition($jQuerySelector, $position, Session $session) { + $session->evaluateScript( + '$("' . $jQuerySelector . '").scrollTop(' . $position . ');' + ); + } + /** * waits till all ajax calls are finished (jQuery.active === 0) * @param Session $session