Commit 3ab885a5 authored by Vincent Petry's avatar Vincent Petry Committed by GitHub

Merge pull request #27404 from owncloud/scrollIntoView

scroll window if element not visible
parents 9c7cd7d8 56213d49
......@@ -146,7 +146,7 @@
this.render();
this.$el.removeClass('hidden');
OC.Util.scrollIntoView(this.$el, null);
OC.showMenu(null, this.$el);
}
});
......
......@@ -2009,6 +2009,32 @@ OC.Util = {
}
}
return false;
},
/**
* Checks if an element is completely visible and scrolls the screen if not
* @param {jQuery} jQuery element that has to be displayed
* @param {jQuery} scroll container if null scrollContainer will be set to $('#app-content')
*/
scrollIntoView: function (toViewEl, scrollContainer) {
var toViewElTopLocation = toViewEl.offset().top;
var toViewElHeight = toViewEl.outerHeight();
var toViewElBottomLocation = toViewElTopLocation + toViewElHeight + 50;
var windowHeight = $(window).height();
if (scrollContainer === null) {
scrollContainer = $('#app-content');
}
if (toViewElBottomLocation > windowHeight) {
var currentPosition = scrollContainer[0].scrollTop;
var scrollDistance = toViewElBottomLocation - windowHeight;
scrollContainer.stop();
scrollContainer.animate({
scrollTop: currentPosition + scrollDistance
}, 700);
}
}
};
......
......@@ -14,6 +14,7 @@ default:
- FeatureContext:
- LoginContext:
- UsersContext:
- FilesContext:
- PersonalSecuritySettingsContext:
<?php
/**
* ownCloud
*
* @author Artur Neumann
* @copyright 2017 Artur Neumann info@individual-it.net
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library 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 library. If not, see <http://www.gnu.org/licenses/>.
*
*/
use Behat\Behat\Context\Context;
use Behat\MinkExtension\Context\RawMinkContext;
use Page\LoginPage;
use Page\FilesPage;
require_once 'bootstrap.php';
/**
* Files context.
*/
class FilesContext extends RawMinkContext implements Context
{
private $loginPage;
private $filesPage;
public function __construct(LoginPage $loginPage, FilesPage $filesPage)
{
$this->loginPage = $loginPage;
$this->filesPage = $filesPage;
}
/**
* @Given I am on the files page
*/
public function iAmOnTheFilesPage()
{
$this->filesPage->open();
}
/**
* @Given the list of files\/folders does not fit in one browser page
*/
public function theListOfFilesFoldersDoesNotFitInOneBrowserPage()
{
$windowHeight = $this->filesPage->getWindowHeight(
$this->getSession()
);
$itemsCount = $this->filesPage->getSizeOfFileFolderList();
$lastItemCoordinates['top'] = 0;
if ($itemsCount > 0) {
$lastItemCoordinates = $this->filesPage->getCoordinatesOfElement(
$this->getSession(),
$this->filesPage->findActionMenuByNo($itemsCount)
);
}
while ($windowHeight > $lastItemCoordinates['top']) {
$this->filesPage->createFolder();
$itemsCount = $this->filesPage->getSizeOfFileFolderList();
$lastItemCoordinates = $this->filesPage->getCoordinatesOfElement(
$this->getSession(),
$this->filesPage->findActionMenuByNo($itemsCount)
);
}
$this->getSession()->reload();
$this->filesPage->waitTillPageIsloaded(10);
}
/**
* @Then The filesactionmenu should be completely visible after clicking on it
*/
public function theFilesactionmenuShouldBeCompletelyVisibleAfterClickingOnIt()
{
for ($i = 1; $i < $this->filesPage->getSizeOfFileFolderList(); $i ++) {
$actionMenu = $this->filesPage->findActionMenuByNo($i);
$actionMenu->click();
$windowHeight = $this->filesPage->getWindowHeight(
$this->getSession()
);
$deleteBtnCoordinates = $this->filesPage->getCoordinatesOfElement(
$this->getSession(), $this->filesPage->findDeleteByNo($i)
);
PHPUnit_Framework_Assert::assertLessThan(
$windowHeight, $deleteBtnCoordinates ["top"]
);
$actionMenu->click();
}
}
}
......@@ -57,10 +57,14 @@ class LoginContext extends RawMinkContext implements Context
}
/**
* @Then a file with the name :filename should be listed
* @Then I should be redirected to a page with the title :title
*/
public function aFileWithTheNameShouldBeListed($filename)
public function iShouldBeRedirectedToAPageWithTheTitle($title)
{
$this->filesPage->findFileInList($filename)->isVisible();
$actualTitle = $this->filesPage->find(
'xpath', './/title'
)->getHtml();
PHPUnit_Framework_Assert::assertEquals($title, $actualTitle);
}
}
Feature: files
@AdminLogin
Scenario: scroll fileactionsmenu into view
Given I am on the files page
And the list of files/folders does not fit in one browser page
Then The filesactionmenu should be completely visible after clicking on it
......@@ -24,6 +24,8 @@
namespace Page;
use SensioLabs\Behat\PageObjectExtension\PageObject\Page;
use SensioLabs\Behat\PageObjectExtension\PageObject\Exception\UnexpectedPageException;
class FilesPage extends OwnCloudPage
{
......@@ -32,28 +34,93 @@ class FilesPage extends OwnCloudPage
* @var string $path
*/
protected $path = '/index.php/apps/files/';
protected $emptyContentXpath = ".//*[@id='emptycontent']";
protected $newFileFolderButtonXpath = './/*[@id="controls"]//a[@class="button new"]';
protected $newFolderButtonXpath = './/div[contains(@class, "newFileMenu")]//a[@data-templatename="New folder"]';
protected $newFolderNameInputLabel = 'New folder';
protected $fileActionMenuXpathByNo = ".//*[@id='fileList']/tr[%d]//a[@data-action='menu']";
protected $fileListXpath = ".//div[@id='app-content-files']//tbody[@id='fileList']";
protected $fileDeleteXpathByNo = ".//*[@id='fileList']/tr[%d]//a[@data-action='Delete']";
private $strForNormalFileName = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
public function findFileInList($filename)
{
return $this->findLink($filename);
}
/**
* created a folder with the given name.
* If name is not given a random one is choosen
*
* @param string $name
*/
public function createFolder($name = null)
{
if ($name === null) {
$name = substr(str_shuffle($this->strForNormalFileName), 0, 8);
}
$this->find("xpath", $this->newFileFolderButtonXpath)->click();
$this->find("xpath", $this->newFolderButtonXpath)->click();
$this->fillField($this->newFolderNameInputLabel, $name . "\n");
return $name;
}
public function getSizeOfFileFolderList()
{
return count(
$this->find("xpath", $this->fileListXpath)->findAll("xpath", "tr")
);
}
public function findActionMenuByNo($number) {
$xpath = sprintf($this->fileActionMenuXpathByNo,$number);
return $this->find("xpath", $xpath);
}
public function findDeleteByNo($number) {
$xpath = sprintf($this->fileDeleteXpathByNo,$number);
return $this->find("xpath", $xpath);
}
//there is no reliable loading indicator on the files page, so waiting for
//the table or the Emplty Folder message to be shown
public function waitTillPageIsloaded($timeout)
{
for ($counter = 0; $counter <= $timeout; $counter ++) {
$fileList = $this->findById("fileList");
if ($fileList !== null &&
($fileList->has("xpath", "//a") || ! $this->find("xpath",
if ($fileList !== null && ($fileList->has("xpath", "//a") || ! $this->find("xpath",
$this->emptyContentXpath)->hasClass("hidden"))) {
break;
}
sleep(1);
}
}
/**
* same as the original open() function but with a more slack
* URL verification as oC adds some extra parameters to the URL e.g.
* "files/?dir=/&fileid=2"
* {@inheritDoc}
* @see \SensioLabs\Behat\PageObjectExtension\PageObject\Page::open()
*/
public function open(array $urlParameters = array())
{
$url = $this->getUrl($urlParameters);
$this->getDriver()->visit($url);
$this->verifyResponse();
if (strpos($this->getDriver()->getCurrentUrl(),
$this->getUrl($urlParameters)) === false) {
throw new UnexpectedPageException(
sprintf('Expected to be on "%s" but found "%s" instead',
$this->getUrl($urlParameters),
$this->getDriver()->getCurrentUrl()));
}
$this->verifyPage();
return $this;
}
}
\ No newline at end of file
......@@ -24,6 +24,7 @@
namespace Page;
use SensioLabs\Behat\PageObjectExtension\PageObject\Page;
use Behat\Mink\Session;
class OwncloudPage extends Page
{
......@@ -56,6 +57,37 @@ class OwncloudPage extends Page
public function getMyUsername() {
return $this->findById($this->userNameDispayId)->getText();
}
/**
* Gets the Coordinates of a Mink Element
*
* @param Session $session
* @param NodeElement $element
* @return Array
*/
public function getCoordinatesOfElement($session, $element)
{
return $session->evaluateScript(
'return document.evaluate( "' .
$element->getXpath() .
'",document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null)' .
'.singleNodeValue.getBoundingClientRect();'
);
}
/**
* Gets the Window Height
*
* @param Session $session
* @return Array
*/
public function getWindowHeight($session)
{
return $session->evaluateScript(
'return $(window).height();'
);
}
/**
* Determine if a Mink NodeElement contains a specific
* css rule attribute value.
......
......@@ -3,4 +3,4 @@ Feature: login
Scenario: simple login
Given I am on login page
When I login with username "admin" and password "admin"
Then a file with the name "welcome.txt" should be listed
\ No newline at end of file
Then I should be redirected to a page with the title "Files - ownCloud"
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment