From e46dc19db27cf1007173f9d8e1110561162b9ceb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Wed, 25 Jul 2018 10:37:29 +0200 Subject: [PATCH 1/4] Add url parameter which open a specific details tab right away --- apps/files/js/app.js | 1 + apps/files/js/filelist.js | 9 ++++++--- apps/files/lib/Controller/ViewController.php | 9 ++++++--- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/apps/files/js/app.js b/apps/files/js/app.js index 830ed6a0cb05..1c23d3745e14 100644 --- a/apps/files/js/app.js +++ b/apps/files/js/app.js @@ -87,6 +87,7 @@ fileActions: fileActions, allowLegacyActions: true, scrollTo: urlParams.scrollto, + detailTabId: urlParams.details, filesClient: OC.Files.getClient(), sorting: { mode: $('#defaultFileSorting').val(), diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index bd25e137d6ad..78f2edf8719b 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -256,7 +256,6 @@ this.$el.toggleClass('hide-hidden-files', !this._filesConfig.get('showhidden')); } - if (_.isUndefined(options.detailsViewEnabled) || options.detailsViewEnabled) { this._detailsView = new OCA.Files.DetailsView(); this._detailsView.$el.insertBefore(this.$el); @@ -333,7 +332,7 @@ if (options.scrollTo) { this.$fileList.one('updated', function() { - self.scrollTo(options.scrollTo); + self.scrollTo(options.scrollTo, options.detailTabId); }); } @@ -2519,10 +2518,14 @@ this.$el.find('.mask').remove(); this.$table.removeClass('hidden'); }, - scrollTo:function(file) { + scrollTo:function(file, detailTabId) { if (!_.isArray(file)) { file = [file]; } + if (!_.isUndefined(detailTabId)) { + var filename = file[file.length - 1]; + this.showDetailsView(filename, detailTabId); + } this.highlightFiles(file, function($tr) { $tr.addClass('searchresult'); $tr.one('hover', function() { diff --git a/apps/files/lib/Controller/ViewController.php b/apps/files/lib/Controller/ViewController.php index b6f4aeceb3a0..2b8eca290d3d 100644 --- a/apps/files/lib/Controller/ViewController.php +++ b/apps/files/lib/Controller/ViewController.php @@ -143,11 +143,11 @@ protected function getStorageInfo() { * @param string $fileid * @return TemplateResponse */ - public function index($dir = '', $view = '', $fileid = null) { + public function index($dir = '', $view = '', $fileid = null, $details = null) { $fileNotFound = false; if ($fileid !== null) { try { - return $this->showFile($fileid); + return $this->showFile($fileid, $details); } catch (NotFoundException $e) { $fileNotFound = true; } @@ -278,7 +278,7 @@ public function index($dir = '', $view = '', $fileid = null) { * @NoCSRFRequired * @NoAdminRequired */ - public function showFile($fileId) { + public function showFile($fileId, $details = null) { $uid = $this->userSession->getUser()->getUID(); $baseFolder = $this->rootFolder->get($uid . '/files/'); $files = $baseFolder->getById($fileId); @@ -308,6 +308,9 @@ public function showFile($fileId) { // and scroll to the entry $params['scrollto'] = $file->getName(); } + if ($details !== null) { + $params['details'] = $details; + } $webUrl = $this->urlGenerator->linkToRoute('files.view.index', $params); $webdavUrl = $this->urlGenerator->linkTo('', 'remote.php') . '/dav/files/' . \rawurlencode($uid) . '/'; From ca0b3f02e67e9de34f865c363ecc5a8496c1b908 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Fri, 27 Jul 2018 16:53:39 +0545 Subject: [PATCH 2/4] webUI acceptance tests for direct browsing to open the details panel --- .../acceptance/features/bootstrap/WebDav.php | 2 +- .../features/bootstrap/WebUIFilesContext.php | 83 +++++++++++++++++++ tests/acceptance/features/lib/FilesPage.php | 10 +++ .../lib/FilesPageElement/SharingDialog.php | 30 +++++++ .../browseDirectlyToDetailsTab.feature | 40 +++++++++ 5 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 tests/acceptance/features/webUIFiles/browseDirectlyToDetailsTab.feature diff --git a/tests/acceptance/features/bootstrap/WebDav.php b/tests/acceptance/features/bootstrap/WebDav.php index 60f287444ff1..0362525d1488 100644 --- a/tests/acceptance/features/bootstrap/WebDav.php +++ b/tests/acceptance/features/bootstrap/WebDav.php @@ -2103,7 +2103,7 @@ public function userDeletesEverythingInFolder($user, $folder) { * * @return int */ - private function getFileIdForPath($user, $path) { + public function getFileIdForPath($user, $path) { try { return WebDavHelper::getFileIdForPath( $this->getBaseUrl(), diff --git a/tests/acceptance/features/bootstrap/WebUIFilesContext.php b/tests/acceptance/features/bootstrap/WebUIFilesContext.php index 6c1c291b296f..1bc174b9253a 100644 --- a/tests/acceptance/features/bootstrap/WebUIFilesContext.php +++ b/tests/acceptance/features/bootstrap/WebUIFilesContext.php @@ -97,6 +97,13 @@ class WebUIFilesContext extends RawMinkContext implements Context { */ private $currentFolder = ""; + /** + * variable to remember with which file we are currently working + * + * @var string + */ + private $currentFile = ""; + /** * * @var FeatureContext @@ -150,6 +157,15 @@ private function getCurrentPageObject() { return $pageObject; } + /** + * get the current folder and file path that is being worked on + * + * @return string + */ + private function getCurrentFolderFilePath() { + return \rtrim($this->currentFolder, '/') . '/' . $this->currentFile; + } + /** * reset any context remembered about where we are or what we have done on * the files-like pages @@ -158,6 +174,7 @@ private function getCurrentPageObject() { */ public function resetFilesContext() { $this->currentFolder = ""; + $this->currentFile = ""; $this->deletedElementsTable = null; $this->movedElementsTable = null; } @@ -181,6 +198,72 @@ public function theUserBrowsesToTheFilesPage() { } } + /** + * @When the user browses directly to display the :tabName details of file :fileName in folder :folderName + * + * @param string $tabName + * @param string $fileName + * @param string $folderName + * @return void + * @throws Exception + */ + public function theUserBrowsesDirectlyToDetailsTabOfFileInFolder( + $tabName, $fileName, $folderName + ) { + $this->currentFolder = '/' . \trim($folderName, '/'); + $this->currentFile = $fileName; + $fileId = $this->featureContext->getFileIdForPath( + $this->featureContext->getCurrentUser(), $this->getCurrentFolderFilePath() + ); + $this->visitPath( + $this->featureContext->getBaseUrl() . '/index.php/apps/files/?dir=' . $folderName . '&fileid=' . $fileId . '&details=' . $tabName + ); + $this->filesPage->waitTillPageIsLoaded($this->getSession()); + } + + /** + * @Then the thumbnail should be visible in the details panel + * + * @return void + * @throws Exception + */ + public function theThumbnailShouldBeVisibleInTheDetailsPanel() { + $sharingDialog = $this->filesPage->getSharingDialog(); + PHPUnit_Framework_Assert::assertContains( + $this->getCurrentFolderFilePath(), + $sharingDialog->findThumbnail()->getAttribute("style") + ); + } + + /** + * @Then the :tabName details panel should be visible + * + * @param string $tabName + * + * @return void + */ + public function theTabNameDetailsPanelShouldBeVisible($tabName) { + $sharingDialog = $this->filesPage->getSharingDialog(); + PHPUnit_Framework_Assert::assertTrue( + $sharingDialog->isDetailsPanelVisible($tabName), + "the $tabName panel is not visible in the details panel" + ); + } + + /** + * @Then the share-with field should be visible in the details panel + * + * @return void + * @throws Exception + */ + public function theShareWithFieldShouldBeVisibleInTheDetailsPanel() { + $sharingDialog = $this->filesPage->getSharingDialog(); + PHPUnit_Framework_Assert::assertTrue( + $sharingDialog->isShareWithFieldVisible(), + 'the share-with field is not visible in the details panel' + ); + } + /** * @When the user browses to the trashbin page * @Given the user has browsed to the trashbin page diff --git a/tests/acceptance/features/lib/FilesPage.php b/tests/acceptance/features/lib/FilesPage.php index 110c3e2f03b7..9e06930bad85 100644 --- a/tests/acceptance/features/lib/FilesPage.php +++ b/tests/acceptance/features/lib/FilesPage.php @@ -213,6 +213,16 @@ public function uploadFile(Session $session, $name) { $this->waitForUploadProgressbarToFinish(); } + /** + * gets a sharing dialog object + * + * @throws ElementNotFoundException + * @return SharingDialog + */ + public function getSharingDialog() { + return $this->getPage("FilesPageElement\\SharingDialog"); + } + /** * opens the sharing dialog for a given file/folder name * returns the SharingDialog Object diff --git a/tests/acceptance/features/lib/FilesPageElement/SharingDialog.php b/tests/acceptance/features/lib/FilesPageElement/SharingDialog.php index 44a757ea7ea6..841dfd916b1d 100644 --- a/tests/acceptance/features/lib/FilesPageElement/SharingDialog.php +++ b/tests/acceptance/features/lib/FilesPageElement/SharingDialog.php @@ -75,6 +75,36 @@ private function _findShareWithField() { return $shareWithField; } + /** + * checks if the requested tab in the details panel is visible + * + * @param string $tabName + * + * @return bool + */ + public function isDetailsPanelVisible($tabName) { + try { + $visible = $this->findById($tabName)->isVisible(); + } catch (ElementNotFoundException $e) { + $visible = false; + } + return $visible; + } + + /** + * checks if the share-with field is visible + * + * @return bool + */ + public function isShareWithFieldVisible() { + try { + $visible = $this->_findShareWithField()->isVisible(); + } catch (ElementNotFoundException $e) { + $visible = false; + } + return $visible; + } + /** * fills the "share-with" input field * diff --git a/tests/acceptance/features/webUIFiles/browseDirectlyToDetailsTab.feature b/tests/acceptance/features/webUIFiles/browseDirectlyToDetailsTab.feature new file mode 100644 index 000000000000..c521b5d1d518 --- /dev/null +++ b/tests/acceptance/features/webUIFiles/browseDirectlyToDetailsTab.feature @@ -0,0 +1,40 @@ +@webUI @insulated +Feature: browse directly to details tab +As a user +I want to be able to browse directly to display the details about a file +So that I can see the details immediately without needing to click in the UI + + Background: + Given these users have been created: + |username|password|displayname|email | + |user1 |1234 |User One |u1@oc.com.np| + And the user has browsed to the login page + And the user has logged in with username "user1" and password "1234" using the webUI + + Scenario Outline: Browse directly to the sharing details of a file + When the user browses directly to display the "shareTabView" details of file "lorem.txt" in folder "" + Then the thumbnail should be visible in the details panel + And the "shareTabView" details panel should be visible + And the share-with field should be visible in the details panel + Examples: + | folder | + | / | + | simple-folder | + + Scenario Outline: Browse directly to the comments details of a file + When the user browses directly to display the "commentsTabView" details of file "lorem.txt" in folder "" + Then the thumbnail should be visible in the details panel + And the "commentsTabView" details panel should be visible + Examples: + | folder | + | / | + | simple-folder | + + Scenario Outline: Browse directly to the versions details of a file + When the user browses directly to display the "versionsTabView" details of file "lorem.txt" in folder "" + Then the thumbnail should be visible in the details panel + And the "versionsTabView" details panel should be visible + Examples: + | folder | + | / | + | simple-folder | From 6c172d7158b5d5b9cdd8464a2679e7762ab2aeb8 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Mon, 30 Jul 2018 14:34:41 +0545 Subject: [PATCH 3/4] Refactor to make DetailsDialog --- .../features/bootstrap/WebUIFilesContext.php | 18 +- .../bootstrap/WebUISharingContext.php | 20 +- tests/acceptance/features/lib/FilesPage.php | 47 ++++- .../lib/FilesPageElement/DetailsDialog.php | 177 ++++++++++++++++++ .../lib/FilesPageElement/SharingDialog.php | 90 --------- .../browseDirectlyToDetailsTab.feature | 12 +- 6 files changed, 252 insertions(+), 112 deletions(-) create mode 100644 tests/acceptance/features/lib/FilesPageElement/DetailsDialog.php diff --git a/tests/acceptance/features/bootstrap/WebUIFilesContext.php b/tests/acceptance/features/bootstrap/WebUIFilesContext.php index 1bc174b9253a..d6d79c545cb4 100644 --- a/tests/acceptance/features/bootstrap/WebUIFilesContext.php +++ b/tests/acceptance/features/bootstrap/WebUIFilesContext.php @@ -72,6 +72,7 @@ class WebUIFilesContext extends RawMinkContext implements Context { * @var ConflictDialog */ private $conflictDialog; + /** * Table of all files and folders that should have been deleted, stored so * that other steps can use the list to check if the deletion happened correctly @@ -215,9 +216,7 @@ public function theUserBrowsesDirectlyToDetailsTabOfFileInFolder( $fileId = $this->featureContext->getFileIdForPath( $this->featureContext->getCurrentUser(), $this->getCurrentFolderFilePath() ); - $this->visitPath( - $this->featureContext->getBaseUrl() . '/index.php/apps/files/?dir=' . $folderName . '&fileid=' . $fileId . '&details=' . $tabName - ); + $this->filesPage->browseToFileId($fileId, $this->currentFolder, $tabName); $this->filesPage->waitTillPageIsLoaded($this->getSession()); } @@ -228,10 +227,15 @@ public function theUserBrowsesDirectlyToDetailsTabOfFileInFolder( * @throws Exception */ public function theThumbnailShouldBeVisibleInTheDetailsPanel() { - $sharingDialog = $this->filesPage->getSharingDialog(); + $detailsDialog = $this->filesPage->getDetailsDialog(); + $style = $detailsDialog->findThumbnail()->getAttribute("style"); + PHPUnit_Framework_Assert::assertNotNull( + $style, + 'style attribute of details thumbnail is null' + ); PHPUnit_Framework_Assert::assertContains( $this->getCurrentFolderFilePath(), - $sharingDialog->findThumbnail()->getAttribute("style") + $style ); } @@ -243,9 +247,9 @@ public function theThumbnailShouldBeVisibleInTheDetailsPanel() { * @return void */ public function theTabNameDetailsPanelShouldBeVisible($tabName) { - $sharingDialog = $this->filesPage->getSharingDialog(); + $detailsDialog = $this->filesPage->getDetailsDialog(); PHPUnit_Framework_Assert::assertTrue( - $sharingDialog->isDetailsPanelVisible($tabName), + $detailsDialog->isDetailsPanelVisible($tabName), "the $tabName panel is not visible in the details panel" ); } diff --git a/tests/acceptance/features/bootstrap/WebUISharingContext.php b/tests/acceptance/features/bootstrap/WebUISharingContext.php index ed511def8cdb..d27b962357d3 100644 --- a/tests/acceptance/features/bootstrap/WebUISharingContext.php +++ b/tests/acceptance/features/bootstrap/WebUISharingContext.php @@ -25,6 +25,7 @@ use Behat\Gherkin\Node\TableNode; use Behat\MinkExtension\Context\RawMinkContext; use Page\FilesPage; +use Page\FilesPageElement\SharingDialog; use Page\PublicLinkFilesPage; use Page\SharedWithYouPage; use SensioLabs\Behat\PageObjectExtension\PageObject\Exception\ElementNotFoundException; @@ -55,6 +56,11 @@ class WebUISharingContext extends RawMinkContext implements Context { * @var SharedWithYouPage */ private $sharedWithYouPage; + + /** + * + * @var SharingDialog + */ private $sharingDialog; /** @@ -125,7 +131,7 @@ public function theUserSharesTheFileFolderWithTheUserUsingTheWebUI( ) { $this->filesPage->waitTillPageIsloaded($this->getSession()); try { - $this->filesPage->closeSharingDialog(); + $this->filesPage->closeDetailsDialog(); } catch (Exception $e) { //we don't care } @@ -160,7 +166,7 @@ public function theUserSharesTheFileFolderWithTheGroupUsingTheWebUI( ) { $this->filesPage->waitTillPageIsloaded($this->getSession()); try { - $this->filesPage->closeSharingDialog(); + $this->filesPage->closeDetailsDialog(); } catch (Exception $e) { //we don't care } @@ -222,7 +228,7 @@ public function theUserCreatesANewPublicLinkForUsingTheWebUIWith( //if there is no dialog open and we try to close it //an exception will be thrown, but we do not care try { - $this->filesPage->closeSharingDialog(); + $this->filesPage->closeDetailsDialog(); } catch (Exception $e) { } $this->sharingDialog = $this->filesPage->openSharingDialog( @@ -274,7 +280,8 @@ public function theUserCreatesANewPublicLinkForUsingTheWebUIWith( * @return void */ public function theUserClosesTheShareDialog() { - $this->sharingDialog->closeSharingDialog(); + // The close button is for the whole details dialog. + $this->filesPage->closeDetailsDialog(); } /** @@ -619,7 +626,7 @@ public function theFileFolderShouldBeMarkedAsSharedBy( //if there is no dialog open and we try to close it //an exception will be thrown, but we do not care try { - $this->filesPage->closeSharingDialog(); + $this->filesPage->closeDetailsDialog(); } catch (Exception $e) { } @@ -639,9 +646,10 @@ public function theFileFolderShouldBeMarkedAsSharedBy( "folder-shared.svg", $row->findThumbnail()->getAttribute("style") ); + $detailsDialog = $this->filesPage->getDetailsDialog(); PHPUnit_Framework_Assert::assertContains( "folder-shared.svg", - $sharingDialog->findThumbnail()->getAttribute("style") + $detailsDialog->findThumbnail()->getAttribute("style") ); } if ($sharedWithGroup !== "") { diff --git a/tests/acceptance/features/lib/FilesPage.php b/tests/acceptance/features/lib/FilesPage.php index 9e06930bad85..2030aff09d90 100644 --- a/tests/acceptance/features/lib/FilesPage.php +++ b/tests/acceptance/features/lib/FilesPage.php @@ -23,6 +23,7 @@ namespace Page; use Behat\Mink\Session; +use Page\FilesPageElement\DetailsDialog; use Page\FilesPageElement\SharingDialog; use SensioLabs\Behat\PageObjectExtension\PageObject\Exception\ElementNotFoundException; use SensioLabs\Behat\PageObjectExtension\PageObject\Exception\UnexpectedPageException; @@ -213,6 +214,16 @@ public function uploadFile(Session $session, $name) { $this->waitForUploadProgressbarToFinish(); } + /** + * gets a details dialog object + * + * @throws ElementNotFoundException + * @return DetailsDialog + */ + public function getDetailsDialog() { + return $this->getPage("FilesPageElement\\DetailsDialog"); + } + /** * gets a sharing dialog object * @@ -238,14 +249,15 @@ public function openSharingDialog($fileName, Session $session) { } /** - * closes an open sharing dialog + * closes an open details dialog + * the details dialog contains the comments, sharing, versions etc tabs * * @throws ElementNotFoundException * if no sharing dialog is open * @return void */ - public function closeSharingDialog() { - $this->getPage('FilesPageElement\\SharingDialog')->closeSharingDialog(); + public function closeDetailsDialog() { + $this->getDetailsDialog()->closeDetailsDialog(); } /** @@ -379,6 +391,35 @@ public function open(array $urlParameters = []) { return $this; } + /** + * Browse directly to a particular file within a folder. + * + * The folder should open and scroll to the requested file. + * If a details tab is specified, then the details panel for that file + * should open with the requested tab selected. + * + * @param string $fileId + * @param string $folderName + * @param string|null $detailsTab e.g. comments, sharing, versions + * + * @return FilesPage + */ + public function browseToFileId( + $fileId, $folderName = '/', $detailsTab = null + ) { + $url = \rtrim($this->getUrl(), '/'); + $fullUrl = $url . '/?dir=' . $folderName . '&fileid=' . $fileId; + + if ($detailsTab !== null) { + $detailsDialog = $this->getDetailsDialog(); + $fullUrl = $fullUrl . '&details=' . $detailsDialog->getDetailsTabId($detailsTab); + } + + $this->getDriver()->visit($fullUrl); + + return $this; + } + /** * waits till the upload progressbar is not visible anymore * diff --git a/tests/acceptance/features/lib/FilesPageElement/DetailsDialog.php b/tests/acceptance/features/lib/FilesPageElement/DetailsDialog.php new file mode 100644 index 000000000000..c1b1d6ce7860 --- /dev/null +++ b/tests/acceptance/features/lib/FilesPageElement/DetailsDialog.php @@ -0,0 +1,177 @@ + + * @copyright Copyright (c) 2018 Phil Davis phil@jankaritech.com + * + * This code 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 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 + * + */ + +namespace Page\FilesPageElement; + +use Behat\Mink\Element\NodeElement; +use Behat\Mink\Session; +use Page\FilesPageElement\SharingDialogElement\PublicLinkTab; +use Page\OwncloudPage; +use SensioLabs\Behat\PageObjectExtension\PageObject\Exception\ElementNotFoundException; + +/** + * The Details Dialog + * + */ +class DetailsDialog extends OwncloudPage { + /** + * + * @var string $path + */ + protected $path = '/index.php/apps/files/'; + + private $detailsDialogCloseXpath = "//div[@id='app-sidebar']//*[@class='close icon-close']"; + private $thumbnailContainerXpath = ".//*[contains(@class,'thumbnailContainer')]"; + private $thumbnailFromContainerXpath = "/a"; + private $detailsTabId = [ + 'comments' => "commentsTabView", + 'sharing' => "shareTabView", + 'versions' => "versionsTabView" + ]; + + /** + * Lookup the id for the requested details tab. + * If the id is not known, then return the passed-in parameter as the id. + * + * @param string $tabName e.g. comments, sharing, versions + * + * @return string + */ + public function getDetailsTabId($tabName) { + if (isset($this->detailsTabId[$tabName])) { + $tabId = $this->detailsTabId[$tabName]; + } else { + $tabId = $tabName; + } + + return $tabId; + } + + /** + * find the element that is the requested details tab + * + * @param string $tabName e.g. comments, sharing, versions + * + * @throws ElementNotFoundException + * @return NodeElement|NULL + */ + private function _findDetailsTab($tabName) { + $tab = $this->findById( + $this->getDetailsTabId($tabName) + ); + if ($tab === null) { + throw new ElementNotFoundException( + __METHOD__ . + " could not find details tab with id $tabName" + ); + } + return $tab; + } + + /** + * checks if the requested tab in the details panel is visible + * + * @param string $tabName + * + * @return bool + */ + public function isDetailsPanelVisible($tabName) { + try { + $visible = $this->_findDetailsTab($tabName)->isVisible(); + } catch (ElementNotFoundException $e) { + $visible = false; + } + return $visible; + } + + /** + * + * @throws ElementNotFoundException + * @return NodeElement of the whole container holding the thumbnail + */ + public function findThumbnailContainer() { + $thumbnailContainer = $this->find("xpath", $this->thumbnailContainerXpath); + if ($thumbnailContainer === null) { + throw new ElementNotFoundException( + __METHOD__ . + " xpath $this->thumbnailContainerXpath " . + "could not find thumbnailContainer" + ); + } + return $thumbnailContainer; + } + + /** + * + * @throws ElementNotFoundException + * @return NodeElement + */ + public function findThumbnail() { + $thumbnailContainer = $this->findThumbnailContainer(); + $thumbnail = $thumbnailContainer->find( + "xpath", $this->thumbnailFromContainerXpath + ); + if ($thumbnail === null) { + throw new ElementNotFoundException( + __METHOD__ . + " xpath $this->thumbnailFromContainerXpath " . + "could not find thumbnail" + ); + } + return $thumbnail; + } + + /** + * closes the details dialog panel + * + * @throws ElementNotFoundException + * @return void + */ + public function closeDetailsDialog() { + $detailsDialogCloseButton = $this->find("xpath", $this->detailsDialogCloseXpath); + if ($detailsDialogCloseButton === null) { + throw new ElementNotFoundException( + __METHOD__ . + " xpath $this->detailsDialogCloseXpath " . + "could not find details-dialog-close-button" + ); + } + + try { + $detailsDialogCloseButton->click(); + } catch (UnknownError $e) { + // Edge often throws UnknownError 'Invalid Argument' when trying to + // click the close button, even though the button was found above. + // Ignore it for now. Many tests could keep working without having + // closed the details dialog. + // TODO: Edge - if it keeps happening then find out why. + \error_log( + __METHOD__ + . " UnknownError while doing detailsDialogCloseButton->click()" + . "\n-------------------------\n" + . $e->getMessage() + . "\n-------------------------\n" + ); + } + } +} diff --git a/tests/acceptance/features/lib/FilesPageElement/SharingDialog.php b/tests/acceptance/features/lib/FilesPageElement/SharingDialog.php index 841dfd916b1d..585672c20aea 100644 --- a/tests/acceptance/features/lib/FilesPageElement/SharingDialog.php +++ b/tests/acceptance/features/lib/FilesPageElement/SharingDialog.php @@ -45,13 +45,10 @@ class SharingDialog extends OwncloudPage { private $shareWithTooltipXpath = "/..//*[@class='tooltip-inner']"; private $shareWithAutocompleteListXpath = ".//ul[contains(@class,'ui-autocomplete')]"; private $autocompleteItemsTextXpath = "//*[@class='autocomplete-item-text']"; - private $shareWithCloseXpath = "//div[@id='app-sidebar']//*[@class='close icon-close']"; private $suffixToIdentifyGroups = " (group)"; private $suffixToIdentifyRemoteUsers = " (federated)"; private $sharerInformationXpath = ".//*[@class='reshare']"; private $sharedWithAndByRegEx = "^(?:[A-Z]\s)?Shared with you(?: and the group (.*))? by (.*)$"; - private $thumbnailContainerXpath = ".//*[contains(@class,'thumbnailContainer')]"; - private $thumbnailFromContainerXpath = "/a"; private $permissionsFieldByUserName = ".//*[@id='shareWithList']//*[@class='has-tooltip username' and .='%s']/.."; private $permissionLabelXpath = ".//label[@for='%s']"; private $showCrudsXpath = ".//*[@class='showCruds']"; @@ -75,22 +72,6 @@ private function _findShareWithField() { return $shareWithField; } - /** - * checks if the requested tab in the details panel is visible - * - * @param string $tabName - * - * @return bool - */ - public function isDetailsPanelVisible($tabName) { - try { - $visible = $this->findById($tabName)->isVisible(); - } catch (ElementNotFoundException $e) { - $visible = false; - } - return $visible; - } - /** * checks if the share-with field is visible * @@ -450,43 +431,6 @@ public function getSharerName() { return $this->getSharedWithGroupAndSharerName()["sharer"]; } - /** - * - * @throws ElementNotFoundException - * @return NodeElement of the whole container holding the thumbnail - */ - public function findThumbnailContainer() { - $thumbnailContainer = $this->find("xpath", $this->thumbnailContainerXpath); - if ($thumbnailContainer === null) { - throw new ElementNotFoundException( - __METHOD__ . - " xpath $this->thumbnailContainerXpath " . - "could not find thumbnailContainer" - ); - } - return $thumbnailContainer; - } - - /** - * - * @throws ElementNotFoundException - * @return NodeElement - */ - public function findThumbnail() { - $thumbnailContainer = $this->findThumbnailContainer(); - $thumbnail = $thumbnailContainer->find( - "xpath", $this->thumbnailFromContainerXpath - ); - if ($thumbnail === null) { - throw new ElementNotFoundException( - __METHOD__ . - " xpath $this->thumbnailFromContainerXpath " . - "could not find thumbnail" - ); - } - return $thumbnail; - } - /** * * @throws ElementNotFoundException @@ -508,38 +452,4 @@ public function openPublicShareTab() { $publicLinkTab->initElement(); return $publicLinkTab; } - - /** - * closes the sharing dialog panel - * - * @throws ElementNotFoundException - * @return void - */ - public function closeSharingDialog() { - $shareDialogCloseButton = $this->find("xpath", $this->shareWithCloseXpath); - if ($shareDialogCloseButton === null) { - throw new ElementNotFoundException( - __METHOD__ . - " xpath $this->shareWithCloseXpath " . - "could not find share-dialog-close-button" - ); - } - - try { - $shareDialogCloseButton->click(); - } catch (UnknownError $e) { - // Edge often throws UnknownError 'Invalid Argument' when trying to - // click the close button, even though the button was found above. - // Ignore it for now. Many tests could keep working without having - // closed the share dialog. - // TODO: Edge - if it keeps happening then find out why. - \error_log( - __METHOD__ - . " UnknownError while doing shareDialogCloseButton->click()" - . "\n-------------------------\n" - . $e->getMessage() - . "\n-------------------------\n" - ); - } - } } diff --git a/tests/acceptance/features/webUIFiles/browseDirectlyToDetailsTab.feature b/tests/acceptance/features/webUIFiles/browseDirectlyToDetailsTab.feature index c521b5d1d518..b90832799466 100644 --- a/tests/acceptance/features/webUIFiles/browseDirectlyToDetailsTab.feature +++ b/tests/acceptance/features/webUIFiles/browseDirectlyToDetailsTab.feature @@ -12,9 +12,9 @@ So that I can see the details immediately without needing to click in the UI And the user has logged in with username "user1" and password "1234" using the webUI Scenario Outline: Browse directly to the sharing details of a file - When the user browses directly to display the "shareTabView" details of file "lorem.txt" in folder "" + When the user browses directly to display the "sharing" details of file "lorem.txt" in folder "" Then the thumbnail should be visible in the details panel - And the "shareTabView" details panel should be visible + And the "sharing" details panel should be visible And the share-with field should be visible in the details panel Examples: | folder | @@ -22,18 +22,18 @@ So that I can see the details immediately without needing to click in the UI | simple-folder | Scenario Outline: Browse directly to the comments details of a file - When the user browses directly to display the "commentsTabView" details of file "lorem.txt" in folder "" + When the user browses directly to display the "comments" details of file "lorem.txt" in folder "" Then the thumbnail should be visible in the details panel - And the "commentsTabView" details panel should be visible + And the "comments" details panel should be visible Examples: | folder | | / | | simple-folder | Scenario Outline: Browse directly to the versions details of a file - When the user browses directly to display the "versionsTabView" details of file "lorem.txt" in folder "" + When the user browses directly to display the "versions" details of file "lorem.txt" in folder "" Then the thumbnail should be visible in the details panel - And the "versionsTabView" details panel should be visible + And the "versions" details panel should be visible Examples: | folder | | / | From 058eaa31d7031673320b3adb42d4f3742612094b Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Mon, 30 Jul 2018 16:03:16 +0545 Subject: [PATCH 4/4] wait for thumbnails or other ajax to happen when browsing to open the details dialog --- .../features/bootstrap/WebUIFilesContext.php | 10 +++-- .../lib/FilesPageElement/DetailsDialog.php | 45 +++++++++++++++++-- .../lib/FilesPageElement/SharingDialog.php | 8 ++-- 3 files changed, 52 insertions(+), 11 deletions(-) diff --git a/tests/acceptance/features/bootstrap/WebUIFilesContext.php b/tests/acceptance/features/bootstrap/WebUIFilesContext.php index d6d79c545cb4..d901a63f1002 100644 --- a/tests/acceptance/features/bootstrap/WebUIFilesContext.php +++ b/tests/acceptance/features/bootstrap/WebUIFilesContext.php @@ -214,10 +214,14 @@ public function theUserBrowsesDirectlyToDetailsTabOfFileInFolder( $this->currentFolder = '/' . \trim($folderName, '/'); $this->currentFile = $fileName; $fileId = $this->featureContext->getFileIdForPath( - $this->featureContext->getCurrentUser(), $this->getCurrentFolderFilePath() + $this->featureContext->getCurrentUser(), + $this->getCurrentFolderFilePath() + ); + $this->filesPage->browseToFileId( + $fileId, $this->currentFolder, $tabName ); - $this->filesPage->browseToFileId($fileId, $this->currentFolder, $tabName); $this->filesPage->waitTillPageIsLoaded($this->getSession()); + $this->filesPage->getDetailsDialog()->waitTillPageIsLoaded($this->getSession()); } /** @@ -232,7 +236,7 @@ public function theThumbnailShouldBeVisibleInTheDetailsPanel() { PHPUnit_Framework_Assert::assertNotNull( $style, 'style attribute of details thumbnail is null' - ); + ); PHPUnit_Framework_Assert::assertContains( $this->getCurrentFolderFilePath(), $style diff --git a/tests/acceptance/features/lib/FilesPageElement/DetailsDialog.php b/tests/acceptance/features/lib/FilesPageElement/DetailsDialog.php index c1b1d6ce7860..ab2c7000e027 100644 --- a/tests/acceptance/features/lib/FilesPageElement/DetailsDialog.php +++ b/tests/acceptance/features/lib/FilesPageElement/DetailsDialog.php @@ -25,7 +25,6 @@ use Behat\Mink\Element\NodeElement; use Behat\Mink\Session; -use Page\FilesPageElement\SharingDialogElement\PublicLinkTab; use Page\OwncloudPage; use SensioLabs\Behat\PageObjectExtension\PageObject\Exception\ElementNotFoundException; @@ -73,9 +72,9 @@ public function getDetailsTabId($tabName) { * @param string $tabName e.g. comments, sharing, versions * * @throws ElementNotFoundException - * @return NodeElement|NULL + * @return NodeElement */ - private function _findDetailsTab($tabName) { + private function findDetailsTab($tabName) { $tab = $this->findById( $this->getDetailsTabId($tabName) ); @@ -97,7 +96,7 @@ private function _findDetailsTab($tabName) { */ public function isDetailsPanelVisible($tabName) { try { - $visible = $this->_findDetailsTab($tabName)->isVisible(); + $visible = $this->findDetailsTab($tabName)->isVisible(); } catch (ElementNotFoundException $e) { $visible = false; } @@ -174,4 +173,42 @@ public function closeDetailsDialog() { ); } } + + /** + * there is no reliable loading indicator on the details dialog page, + * so wait for the thumbnail to be there with a style attribute. + * this should happen both when previews are enabled and disabled. + * + * @param Session $session + * @param int $timeout_msec + * + * @return void + * @throws \Exception + */ + public function waitTillPageIsLoaded( + Session $session, + $timeout_msec = STANDARDUIWAITTIMEOUTMILLISEC + ) { + $currentTime = \microtime(true); + $end = $currentTime + ($timeout_msec / 1000); + while ($currentTime <= $end) { + try { + if ($this->findThumbnail()->getAttribute("style") !== null) { + break; + } + } catch (ElementNotFoundException $e) { + // Just loop and try again if the element was not found yet. + } + \usleep(STANDARDSLEEPTIMEMICROSEC); + $currentTime = \microtime(true); + } + + if ($currentTime > $end) { + throw new \Exception( + __METHOD__ . " timeout waiting for page to load" + ); + } + + $this->waitForOutstandingAjaxCalls($session); + } } diff --git a/tests/acceptance/features/lib/FilesPageElement/SharingDialog.php b/tests/acceptance/features/lib/FilesPageElement/SharingDialog.php index 585672c20aea..efcfb4db9445 100644 --- a/tests/acceptance/features/lib/FilesPageElement/SharingDialog.php +++ b/tests/acceptance/features/lib/FilesPageElement/SharingDialog.php @@ -61,7 +61,7 @@ class SharingDialog extends OwncloudPage { * @throws ElementNotFoundException * @return NodeElement|NULL */ - private function _findShareWithField() { + private function findShareWithField() { $shareWithField = $this->find("xpath", $this->shareWithFieldXpath); if ($shareWithField === null) { throw new ElementNotFoundException( @@ -79,7 +79,7 @@ private function _findShareWithField() { */ public function isShareWithFieldVisible() { try { - $visible = $this->_findShareWithField()->isVisible(); + $visible = $this->findShareWithField()->isVisible(); } catch (ElementNotFoundException $e) { $visible = false; } @@ -98,7 +98,7 @@ public function isShareWithFieldVisible() { public function fillShareWithField( $input, Session $session, $timeout_msec = STANDARDUIWAITTIMEOUTMILLISEC ) { - $shareWithField = $this->_findShareWithField(); + $shareWithField = $this->findShareWithField(); $this->fillFieldAndKeepFocus($shareWithField, $input, $session); $this->waitForAjaxCallsToStartAndFinish($session, $timeout_msec); return $this->getAutocompleteNodeElement(); @@ -354,7 +354,7 @@ public function setSharingPermissions( * @return string */ public function getShareWithTooltip() { - $shareWithField = $this->_findShareWithField(); + $shareWithField = $this->findShareWithField(); $shareWithTooltip = $shareWithField->find( "xpath", $this->shareWithTooltipXpath );