1
0

FilesAppSharingContext.php 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811
  1. <?php
  2. /**
  3. *
  4. * @copyright Copyright (c) 2018, Daniel Calviño Sánchez (danxuliu@gmail.com)
  5. *
  6. * @license GNU AGPL version 3 or any later version
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU Affero General Public License as
  10. * published by the Free Software Foundation, either version 3 of the
  11. * License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU Affero General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Affero General Public License
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. *
  21. */
  22. use Behat\Behat\Context\Context;
  23. use PHPUnit\Framework\Assert;
  24. use WebDriver\Key;
  25. class FilesAppSharingContext implements Context, ActorAwareInterface {
  26. use ActorAware;
  27. /**
  28. * @return Locator
  29. */
  30. public static function sharedByLabel() {
  31. return Locator::forThe()->css(".sharing-entry__reshare")->
  32. descendantOf(FilesAppContext::detailsView())->
  33. describedAs("Shared by label in the details view in Files app");
  34. }
  35. /**
  36. * @return Locator
  37. */
  38. public static function shareWithInput() {
  39. return Locator::forThe()->css(".sharing-search__input input")->
  40. descendantOf(FilesAppContext::detailsView())->
  41. describedAs("Share with input in the details view in Files app");
  42. }
  43. /**
  44. * @return Locator
  45. */
  46. public static function shareWithInputResults() {
  47. return Locator::forThe()->css(".vs__dropdown-menu")->
  48. describedAs("Share with input results list in the details view in Files app");
  49. }
  50. /**
  51. * @return Locator
  52. */
  53. public static function shareWithInputResult($result) {
  54. return Locator::forThe()->xpath("//li//span[normalize-space() = '$result']/ancestor::li")->
  55. descendantOf(self::shareWithInputResults())->
  56. describedAs("Share with input result from the results list in the details view in Files app");
  57. }
  58. /**
  59. * @return Locator
  60. */
  61. public static function shareeList() {
  62. return Locator::forThe()->css(".sharing-sharee-list")->
  63. descendantOf(FilesAppContext::detailsView())->
  64. describedAs("Sharee list in the details view in Files app");
  65. }
  66. /**
  67. * @return Locator
  68. */
  69. public static function sharedWithRow($sharedWithName) {
  70. // "username" class is used for any type of share, not only for shares
  71. // with users.
  72. return Locator::forThe()->xpath("//li[contains(concat(' ', normalize-space(@class), ' '), ' sharing-entry ')]//span[normalize-space() = '$sharedWithName']/ancestor::li")->
  73. descendantOf(self::shareeList())->
  74. describedAs("Shared with $sharedWithName row in the details view in Files app");
  75. }
  76. /**
  77. * @return Locator
  78. */
  79. public static function shareWithMenuTrigger($sharedWithName) {
  80. return Locator::forThe()->css(".sharing-entry__actions button")->
  81. descendantOf(self::sharedWithRow($sharedWithName))->
  82. describedAs("Share with $sharedWithName menu trigger in the details view in Files app");
  83. }
  84. /**
  85. * @return Locator
  86. */
  87. public static function shareWithMenuButton($sharedWithName) {
  88. return Locator::forThe()->css(".action-item__menutoggle")->
  89. descendantOf(self::shareWithMenuTrigger($sharedWithName))->
  90. describedAs("Share with $sharedWithName menu button in the details view in Files app");
  91. }
  92. /**
  93. * @return Locator
  94. */
  95. public static function shareWithMenu($sharedWithName, $shareWithMenuTriggerElement) {
  96. return Locator::forThe()->xpath("//*[@id = " . $shareWithMenuTriggerElement->getWrappedElement()->getXpath() . "/@aria-describedby]")->
  97. describedAs("Share with $sharedWithName menu in the details view in Files app");
  98. }
  99. /**
  100. * @return Locator
  101. */
  102. public static function permissionCheckboxFor($sharedWithName, $shareWithMenuTriggerElement, $itemText) {
  103. // forThe()->checkbox($itemText) can not be used here; that would return
  104. // the checkbox itself, but the element that the user interacts with is
  105. // the label.
  106. return Locator::forThe()->xpath("//label[normalize-space() = '$itemText']")->
  107. descendantOf(self::shareWithMenu($sharedWithName, $shareWithMenuTriggerElement))->
  108. describedAs("$itemText checkbox in the share with $sharedWithName menu in the details view in Files app");
  109. }
  110. /**
  111. * @return Locator
  112. */
  113. public static function permissionCheckboxInputFor($sharedWithName, $shareWithMenuTriggerElement, $itemText) {
  114. return Locator::forThe()->checkbox($itemText)->
  115. descendantOf(self::shareWithMenu($sharedWithName, $shareWithMenuTriggerElement))->
  116. describedAs("$itemText checkbox input in the share with $sharedWithName menu in the details view in Files app");
  117. }
  118. /**
  119. * @return Locator
  120. */
  121. public static function canEditCheckbox($sharedWithName, $shareWithMenuTriggerElement) {
  122. return self::permissionCheckboxFor($sharedWithName, $shareWithMenuTriggerElement, 'Allow editing');
  123. }
  124. /**
  125. * @return Locator
  126. */
  127. public static function canEditCheckboxInput($sharedWithName, $shareWithMenuTriggerElement) {
  128. return self::permissionCheckboxInputFor($sharedWithName, $shareWithMenuTriggerElement, 'Allow editing');
  129. }
  130. /**
  131. * @return Locator
  132. */
  133. public static function canCreateCheckbox($sharedWithName, $shareWithMenuTriggerElement) {
  134. return self::permissionCheckboxFor($sharedWithName, $shareWithMenuTriggerElement, 'Allow creating');
  135. }
  136. /**
  137. * @return Locator
  138. */
  139. public static function canCreateCheckboxInput($sharedWithName, $shareWithMenuTriggerElement) {
  140. return self::permissionCheckboxInputFor($sharedWithName, $shareWithMenuTriggerElement, 'Allow creating');
  141. }
  142. /**
  143. * @return Locator
  144. */
  145. public static function canReshareCheckbox($sharedWithName, $shareWithMenuTriggerElement) {
  146. return self::permissionCheckboxFor($sharedWithName, $shareWithMenuTriggerElement, 'Allow resharing');
  147. }
  148. /**
  149. * @return Locator
  150. */
  151. public static function canReshareCheckboxInput($sharedWithName, $shareWithMenuTriggerElement) {
  152. return self::permissionCheckboxInputFor($sharedWithName, $shareWithMenuTriggerElement, 'Allow resharing');
  153. }
  154. /**
  155. * @return Locator
  156. */
  157. public static function unshareButton($sharedWithName, $shareWithMenuTriggerElement) {
  158. return Locator::forThe()->xpath("//li[contains(concat(' ', normalize-space(@class), ' '), ' action ')]//button[normalize-space() = 'Unshare']")->
  159. descendantOf(self::shareWithMenu($sharedWithName, $shareWithMenuTriggerElement))->
  160. describedAs("Unshare button in the share with $sharedWithName menu in the details view in Files app");
  161. }
  162. /**
  163. * @return Locator
  164. */
  165. public static function shareLinkRow() {
  166. return Locator::forThe()->css(".sharing-link-list .sharing-entry__link:first-child")->
  167. descendantOf(FilesAppContext::detailsView())->
  168. describedAs("Share link row in the details view in Files app");
  169. }
  170. /**
  171. * @return Locator
  172. */
  173. public static function shareLinkAddNewButton() {
  174. // When there is no link share the "Add new share" item is shown instead
  175. // of the menu button as a direct child of ".share-menu".
  176. return Locator::forThe()->css(".action-item.new-share-link")->
  177. descendantOf(self::shareLinkRow())->
  178. describedAs("Add new share link button in the details view in Files app");
  179. }
  180. /**
  181. * @return Locator
  182. */
  183. public static function copyLinkButton() {
  184. return Locator::forThe()->css("a.sharing-entry__copy")->
  185. descendantOf(self::shareLinkRow())->
  186. describedAs("Copy link button in the details view in Files app");
  187. }
  188. /**
  189. * @return Locator
  190. */
  191. public static function shareLinkMenuTrigger() {
  192. return Locator::forThe()->css(".sharing-entry__actions .action-item__menutoggle")->
  193. descendantOf(self::shareLinkRow())->
  194. describedAs("Share link menu trigger in the details view in Files app");
  195. }
  196. /**
  197. * @return Locator
  198. */
  199. public static function shareLinkSingleUnshareAction() {
  200. return Locator::forThe()->css(".sharing-entry__actions.icon-close")->
  201. descendantOf(self::shareLinkRow())->
  202. describedAs("Unshare link single action in the details view in Files app");
  203. }
  204. /**
  205. * @return Locator
  206. */
  207. public static function shareLinkMenuButton() {
  208. return Locator::forThe()->css(".action-item__menutoggle")->
  209. descendantOf(self::shareLinkMenuTrigger())->
  210. describedAs("Share link menu button in the details view in Files app");
  211. }
  212. /**
  213. * @return Locator
  214. */
  215. public static function shareLinkMenu($shareLinkMenuTriggerElement) {
  216. return Locator::forThe()->xpath("//*[@id = " . $shareLinkMenuTriggerElement->getWrappedElement()->getXpath() . "/@aria-describedby]")->
  217. describedAs("Share link menu in the details view in Files app");
  218. }
  219. /**
  220. * @return Locator
  221. */
  222. public static function hideDownloadCheckbox($shareLinkMenuTriggerElement) {
  223. // forThe()->checkbox("Hide download") can not be used here; that would
  224. // return the checkbox itself, but the element that the user interacts
  225. // with is the label.
  226. return Locator::forThe()->xpath("//label[normalize-space() = 'Hide download']")->
  227. descendantOf(self::shareLinkMenu($shareLinkMenuTriggerElement))->
  228. describedAs("Hide download checkbox in the details view in Files app");
  229. }
  230. /**
  231. * @return Locator
  232. */
  233. public static function hideDownloadCheckboxInput($shareLinkMenuTriggerElement) {
  234. return Locator::forThe()->checkbox("Hide download")->
  235. descendantOf(self::shareLinkMenu($shareLinkMenuTriggerElement))->
  236. describedAs("Hide download checkbox input in the details view in Files app");
  237. }
  238. /**
  239. * @return Locator
  240. */
  241. public static function allowUploadAndEditingRadioButton($shareLinkMenuTriggerElement) {
  242. // forThe()->radio("Allow upload and editing") can not be used here;
  243. // that would return the radio button itself, but the element that the
  244. // user interacts with is the label.
  245. return Locator::forThe()->xpath("//label[normalize-space() = 'Allow upload and editing']")->
  246. descendantOf(self::shareLinkMenu($shareLinkMenuTriggerElement))->
  247. describedAs("Allow upload and editing radio button in the details view in Files app");
  248. }
  249. /**
  250. * @return Locator
  251. */
  252. public static function passwordProtectCheckbox($shareLinkMenuTriggerElement) {
  253. // forThe()->checkbox("Password protect") can not be used here; that
  254. // would return the checkbox itself, but the element that the user
  255. // interacts with is the label.
  256. return Locator::forThe()->xpath("//label[normalize-space() = 'Password protect']")->
  257. descendantOf(self::shareLinkMenu($shareLinkMenuTriggerElement))->
  258. describedAs("Password protect checkbox in the details view in Files app");
  259. }
  260. /**
  261. * @return Locator
  262. */
  263. public static function passwordProtectCheckboxInput($shareLinkMenuTriggerElement) {
  264. return Locator::forThe()->checkbox("Password protect")->
  265. descendantOf(self::shareLinkMenu($shareLinkMenuTriggerElement))->
  266. describedAs("Password protect checkbox input in the details view in Files app");
  267. }
  268. /**
  269. * @return Locator
  270. */
  271. public static function passwordProtectField($shareLinkMenuTriggerElement) {
  272. return Locator::forThe()->css(".share-link-password input.input-field__input")->descendantOf(self::shareLinkMenu($shareLinkMenuTriggerElement))->
  273. describedAs("Password protect field in the details view in Files app");
  274. }
  275. /**
  276. * @return Locator
  277. */
  278. public static function disabledPasswordProtectField($shareLinkMenuTriggerElement) {
  279. return Locator::forThe()->css(".share-link-password input.input-field__input[disabled]")->descendantOf(self::shareLinkMenu($shareLinkMenuTriggerElement))->
  280. describedAs("Disabled password protect field in the details view in Files app");
  281. }
  282. /**
  283. * @return Locator
  284. */
  285. public static function passwordProtectByTalkCheckbox($shareLinkMenuTriggerElement) {
  286. // forThe()->checkbox("Password protect by Talk") can not be used here;
  287. // that would return the checkbox itself, but the element that the user
  288. // interacts with is the label.
  289. return Locator::forThe()->xpath("//label[normalize-space() = 'Password protect by Talk']")->
  290. descendantOf(self::shareLinkMenu($shareLinkMenuTriggerElement))->
  291. describedAs("Password protect by Talk checkbox in the details view in Files app");
  292. }
  293. /**
  294. * @return Locator
  295. */
  296. public static function passwordProtectByTalkCheckboxInput($shareLinkMenuTriggerElement) {
  297. return Locator::forThe()->checkbox("Password protect by Talk")->
  298. descendantOf(self::shareLinkMenu($shareLinkMenuTriggerElement))->
  299. describedAs("Password protect by Talk checkbox input in the details view in Files app");
  300. }
  301. /**
  302. * @return Locator
  303. */
  304. public static function unshareLinkButton($shareLinkMenuTriggerElement) {
  305. return Locator::forThe()->xpath("//li[contains(concat(' ', normalize-space(@class), ' '), ' action ')]//button[normalize-space() = 'Unshare']")->
  306. descendantOf(self::shareLinkMenu($shareLinkMenuTriggerElement))->
  307. describedAs("Unshare link button in the details view in Files app");
  308. }
  309. /**
  310. * @Given I share the link for :fileName
  311. */
  312. public function iShareTheLinkFor($fileName) {
  313. $this->actor->find(FileListContext::shareActionForFile(FilesAppContext::currentSectionMainView(), $fileName), 10)->click();
  314. $this->actor->find(self::shareLinkAddNewButton(), 5)->click();
  315. }
  316. /**
  317. * @Given I share :fileName with :shareWithName
  318. */
  319. public function iShareWith($fileName, $shareWithName) {
  320. $this->actor->find(FileListContext::shareActionForFile(FilesAppContext::currentSectionMainView(), $fileName), 10)->click();
  321. $this->actor->find(self::shareWithInput(), 5)->setValue($shareWithName);
  322. // "setValue()" ends sending a tab, which unfocuses the input and causes
  323. // the results to be hidden, so the input needs to be clicked to show
  324. // the results again.
  325. $this->actor->find(self::shareWithInput())->click();
  326. $this->actor->find(self::shareWithInputResult($shareWithName), 5)->click();
  327. }
  328. /**
  329. * @Given I write down the shared link
  330. */
  331. public function iWriteDownTheSharedLink() {
  332. $shareLinkMenuTriggerElement = $this->actor->find(self::shareLinkMenuTrigger(), 2);
  333. // Close the share link menu if it is open to ensure that it does not
  334. // cover the copy link button.
  335. if (!WaitFor::elementToBeEventuallyNotShown(
  336. $this->actor,
  337. self::shareLinkMenu($shareLinkMenuTriggerElement),
  338. $timeout = 2 * $this->actor->getFindTimeoutMultiplier())) {
  339. // It may not be possible to click on the menu button (due to the
  340. // menu itself covering it), so "Enter" key is pressed instead.
  341. $this->actor->find(self::shareLinkMenuButton(), 2)->getWrappedElement()->keyPress(13);
  342. }
  343. $this->actor->find(self::copyLinkButton(), 10)->click();
  344. // Clicking on the menu item copies the link to the clipboard, but it is
  345. // not possible to access that value from the acceptance tests. Due to
  346. // this the value of the attribute that holds the URL is used instead.
  347. $this->actor->getSharedNotebook()["shared link"] = $this->actor->find(self::copyLinkButton(), 2)->getWrappedElement()->getAttribute("href");
  348. }
  349. /**
  350. * @When I set the download of the shared link as hidden
  351. */
  352. public function iSetTheDownloadOfTheSharedLinkAsHidden() {
  353. $this->showShareLinkMenuIfNeeded();
  354. $this->iSeeThatTheDownloadOfTheLinkShareIsShown();
  355. $shareLinkMenuTriggerElement = $this->actor->find(self::shareLinkMenuTrigger(), 2);
  356. $this->actor->find(self::hideDownloadCheckbox($shareLinkMenuTriggerElement), 2)->click();
  357. }
  358. /**
  359. * @When I set the download of the shared link as shown
  360. */
  361. public function iSetTheDownloadOfTheSharedLinkAsShown() {
  362. $this->showShareLinkMenuIfNeeded();
  363. $this->iSeeThatTheDownloadOfTheLinkShareIsHidden();
  364. $shareLinkMenuTriggerElement = $this->actor->find(self::shareLinkMenuTrigger(), 2);
  365. $this->actor->find(self::hideDownloadCheckbox($shareLinkMenuTriggerElement), 2)->click();
  366. }
  367. /**
  368. * @When I set the shared link as editable
  369. */
  370. public function iSetTheSharedLinkAsEditable() {
  371. $this->showShareLinkMenuIfNeeded();
  372. $shareLinkMenuTriggerElement = $this->actor->find(self::shareLinkMenuTrigger(), 2);
  373. $this->actor->find(self::allowUploadAndEditingRadioButton($shareLinkMenuTriggerElement), 2)->click();
  374. }
  375. /**
  376. * @When I protect the shared link with the password :password
  377. */
  378. public function iProtectTheSharedLinkWithThePassword($password) {
  379. $this->showShareLinkMenuIfNeeded();
  380. $shareLinkMenuTriggerElement = $this->actor->find(self::shareLinkMenuTrigger(), 2);
  381. $this->actor->find(self::passwordProtectCheckbox($shareLinkMenuTriggerElement), 2)->click();
  382. $this->actor->find(self::passwordProtectField($shareLinkMenuTriggerElement), 2)->setValue($password . Key::ENTER);
  383. }
  384. /**
  385. * @When I set the password of the shared link as protected by Talk
  386. */
  387. public function iSetThePasswordOfTheSharedLinkAsProtectedByTalk() {
  388. $this->showShareLinkMenuIfNeeded();
  389. $this->iSeeThatThePasswordOfTheLinkShareIsNotProtectedByTalk();
  390. $shareLinkMenuTriggerElement = $this->actor->find(self::shareLinkMenuTrigger(), 2);
  391. $this->actor->find(self::passwordProtectByTalkCheckbox($shareLinkMenuTriggerElement), 2)->click();
  392. }
  393. /**
  394. * @When I set the password of the shared link as not protected by Talk
  395. */
  396. public function iSetThePasswordOfTheSharedLinkAsNotProtectedByTalk() {
  397. $this->showShareLinkMenuIfNeeded();
  398. $this->iSeeThatThePasswordOfTheLinkShareIsProtectedByTalk();
  399. $shareLinkMenuTriggerElement = $this->actor->find(self::shareLinkMenuTrigger(), 2);
  400. $this->actor->find(self::passwordProtectByTalkCheckbox($shareLinkMenuTriggerElement), 2)->click();
  401. }
  402. /**
  403. * @When I set the share with :shareWithName as not editable
  404. */
  405. public function iSetTheShareWithAsNotEditable($shareWithName) {
  406. $this->showShareWithMenuIfNeeded($shareWithName);
  407. $this->iSeeThatCanEditTheShare($shareWithName);
  408. $shareWithMenuTriggerElement = $this->actor->find(self::shareWithMenuTrigger($shareWithName), 2);
  409. $this->actor->find(self::canEditCheckbox($shareWithName, $shareWithMenuTriggerElement), 2)->click();
  410. }
  411. /**
  412. * @When I set the share with :shareWithName as not creatable
  413. */
  414. public function iSetTheShareWithAsNotCreatable($shareWithName) {
  415. $this->showShareWithMenuIfNeeded($shareWithName);
  416. $this->iSeeThatCanCreateInTheShare($shareWithName);
  417. $shareWithMenuTriggerElement = $this->actor->find(self::shareWithMenuTrigger($shareWithName), 2);
  418. $this->actor->find(self::canCreateCheckbox($shareWithName, $shareWithMenuTriggerElement), 2)->click();
  419. }
  420. /**
  421. * @When I set the share with :shareWithName as not reshareable
  422. */
  423. public function iSetTheShareWithAsNotReshareable($shareWithName) {
  424. $this->showShareWithMenuIfNeeded($shareWithName);
  425. $this->iSeeThatCanReshareTheShare($shareWithName);
  426. $shareWithMenuTriggerElement = $this->actor->find(self::shareWithMenuTrigger($shareWithName), 2);
  427. $this->actor->find(self::canReshareCheckbox($shareWithName, $shareWithMenuTriggerElement), 2)->click();
  428. }
  429. /**
  430. * @When I unshare the share with :shareWithName
  431. */
  432. public function iUnshareTheFileWith($shareWithName) {
  433. $this->showShareWithMenuIfNeeded($shareWithName);
  434. $shareWithMenuTriggerElement = $this->actor->find(self::shareWithMenuTrigger($shareWithName), 2);
  435. $this->actor->find(self::unshareButton($shareWithName, $shareWithMenuTriggerElement), 2)->click();
  436. }
  437. /**
  438. * @When I unshare the link share
  439. */
  440. public function iUnshareTheLink() {
  441. try {
  442. $this->actor->find(self::shareLinkSingleUnshareAction(), 2)->click();
  443. } catch (NoSuchElementException $e) {
  444. $this->showShareLinkMenuIfNeeded();
  445. $shareLinkMenuTriggerElement = $this->actor->find(self::shareLinkMenuTrigger(), 2);
  446. $this->actor->find(self::unshareLinkButton($shareLinkMenuTriggerElement), 2)->click();
  447. }
  448. }
  449. /**
  450. * @Then I see that the file is shared with me by :sharedByName
  451. */
  452. public function iSeeThatTheFileIsSharedWithMeBy($sharedByName) {
  453. Assert::assertEquals(
  454. $this->actor->find(self::sharedByLabel(), 10)->getText(), "Shared with you by $sharedByName");
  455. }
  456. /**
  457. * @Then I see that the file is shared with :sharedWithName
  458. */
  459. public function iSeeThatTheFileIsSharedWith($sharedWithName) {
  460. Assert::assertTrue(
  461. $this->actor->find(self::sharedWithRow($sharedWithName), 10)->isVisible());
  462. }
  463. /**
  464. * @Then I see that the file is not shared with :sharedWithName
  465. */
  466. public function iSeeThatTheFileIsNotSharedWith($sharedWithName) {
  467. if (!WaitFor::elementToBeEventuallyNotShown(
  468. $this->actor,
  469. self::sharedWithRow($sharedWithName),
  470. $timeout = 10 * $this->actor->getFindTimeoutMultiplier())) {
  471. Assert::fail("The shared with $sharedWithName row is still shown after $timeout seconds");
  472. }
  473. }
  474. /**
  475. * @Then I see that resharing the file is not allowed
  476. */
  477. public function iSeeThatResharingTheFileIsNotAllowed() {
  478. Assert::assertEquals(
  479. $this->actor->find(self::shareWithInput(), 10)->getWrappedElement()->getAttribute("disabled"), "disabled");
  480. Assert::assertEquals(
  481. $this->actor->find(self::shareWithInput(), 10)->getWrappedElement()->getAttribute("placeholder"), "Resharing is not allowed");
  482. }
  483. /**
  484. * @Then I see that resharing the file by link is not available
  485. */
  486. public function iSeeThatResharingTheFileByLinkIsNotAvailable() {
  487. if (!WaitFor::elementToBeEventuallyNotShown(
  488. $this->actor,
  489. self::shareLinkAddNewButton(),
  490. $timeout = 10 * $this->actor->getFindTimeoutMultiplier())) {
  491. Assert::fail("The add new share link button is still shown after $timeout seconds");
  492. }
  493. }
  494. /**
  495. * @Then I see that :sharedWithName can not be allowed to edit the share
  496. */
  497. public function iSeeThatCanNotBeAllowedToEditTheShare($sharedWithName) {
  498. $this->showShareWithMenuIfNeeded($sharedWithName);
  499. $shareWithMenuTriggerElement = $this->actor->find(self::shareWithMenuTrigger($sharedWithName), 10);
  500. Assert::assertEquals(
  501. $this->actor->find(self::canEditCheckboxInput($sharedWithName, $shareWithMenuTriggerElement), 10)->getWrappedElement()->getAttribute("disabled"), "disabled");
  502. }
  503. /**
  504. * @Then I see that :sharedWithName can edit the share
  505. */
  506. public function iSeeThatCanEditTheShare($sharedWithName) {
  507. $this->showShareWithMenuIfNeeded($sharedWithName);
  508. $shareWithMenuTriggerElement = $this->actor->find(self::shareWithMenuTrigger($sharedWithName), 10);
  509. Assert::assertTrue(
  510. $this->actor->find(self::canEditCheckboxInput($sharedWithName, $shareWithMenuTriggerElement), 10)->isChecked());
  511. }
  512. /**
  513. * @Then I see that :sharedWithName can not edit the share
  514. */
  515. public function iSeeThatCanNotEditTheShare($sharedWithName) {
  516. $this->showShareWithMenuIfNeeded($sharedWithName);
  517. $shareWithMenuTriggerElement = $this->actor->find(self::shareWithMenuTrigger($sharedWithName), 10);
  518. Assert::assertFalse(
  519. $this->actor->find(self::canEditCheckboxInput($sharedWithName, $shareWithMenuTriggerElement), 10)->isChecked());
  520. }
  521. /**
  522. * @Then I see that :sharedWithName can not be allowed to create in the share
  523. */
  524. public function iSeeThatCanNotBeAllowedToCreateInTheShare($sharedWithName) {
  525. $this->showShareWithMenuIfNeeded($sharedWithName);
  526. $shareWithMenuTriggerElement = $this->actor->find(self::shareWithMenuTrigger($sharedWithName), 10);
  527. Assert::assertEquals(
  528. $this->actor->find(self::canCreateCheckboxInput($sharedWithName, $shareWithMenuTriggerElement), 10)->getWrappedElement()->getAttribute("disabled"), "disabled");
  529. }
  530. /**
  531. * @Then I see that :sharedWithName can create in the share
  532. */
  533. public function iSeeThatCanCreateInTheShare($sharedWithName) {
  534. $this->showShareWithMenuIfNeeded($sharedWithName);
  535. $shareWithMenuTriggerElement = $this->actor->find(self::shareWithMenuTrigger($sharedWithName), 10);
  536. Assert::assertTrue(
  537. $this->actor->find(self::canCreateCheckboxInput($sharedWithName, $shareWithMenuTriggerElement), 10)->isChecked());
  538. }
  539. /**
  540. * @Then I see that :sharedWithName can not create in the share
  541. */
  542. public function iSeeThatCanNotCreateInTheShare($sharedWithName) {
  543. $this->showShareWithMenuIfNeeded($sharedWithName);
  544. $shareWithMenuTriggerElement = $this->actor->find(self::shareWithMenuTrigger($sharedWithName), 10);
  545. Assert::assertFalse(
  546. $this->actor->find(self::canCreateCheckboxInput($sharedWithName, $shareWithMenuTriggerElement), 10)->isChecked());
  547. }
  548. /**
  549. * @Then I see that resharing for :sharedWithName is not available
  550. */
  551. public function iSeeThatResharingForIsNotAvailable($sharedWithName) {
  552. $this->showShareWithMenuIfNeeded($sharedWithName);
  553. $shareWithMenuTriggerElement = $this->actor->find(self::shareWithMenuTrigger($sharedWithName), 10);
  554. if (!WaitFor::elementToBeEventuallyNotShown(
  555. $this->actor,
  556. self::canReshareCheckbox($sharedWithName, $shareWithMenuTriggerElement),
  557. $timeout = 10 * $this->actor->getFindTimeoutMultiplier())) {
  558. Assert::fail("The resharing checkbox for $sharedWithName is still shown after $timeout seconds");
  559. }
  560. }
  561. /**
  562. * @Then I see that :sharedWithName can reshare the share
  563. */
  564. public function iSeeThatCanReshareTheShare($sharedWithName) {
  565. $this->showShareWithMenuIfNeeded($sharedWithName);
  566. $shareWithMenuTriggerElement = $this->actor->find(self::shareWithMenuTrigger($sharedWithName), 10);
  567. Assert::assertTrue(
  568. $this->actor->find(self::canReshareCheckboxInput($sharedWithName, $shareWithMenuTriggerElement), 10)->isChecked());
  569. }
  570. /**
  571. * @Then I see that :sharedWithName can not reshare the share
  572. */
  573. public function iSeeThatCanNotReshareTheShare($sharedWithName) {
  574. $this->showShareWithMenuIfNeeded($sharedWithName);
  575. $shareWithMenuTriggerElement = $this->actor->find(self::shareWithMenuTrigger($sharedWithName), 10);
  576. Assert::assertFalse(
  577. $this->actor->find(self::canReshareCheckboxInput($sharedWithName, $shareWithMenuTriggerElement), 10)->isChecked());
  578. }
  579. /**
  580. * @Then I see that the download of the link share is hidden
  581. */
  582. public function iSeeThatTheDownloadOfTheLinkShareIsHidden() {
  583. $this->showShareLinkMenuIfNeeded();
  584. $shareLinkMenuTriggerElement = $this->actor->find(self::shareLinkMenuTrigger(), 10);
  585. Assert::assertTrue($this->actor->find(self::hideDownloadCheckboxInput($shareLinkMenuTriggerElement), 10)->isChecked());
  586. }
  587. /**
  588. * @Then I see that the download of the link share is shown
  589. */
  590. public function iSeeThatTheDownloadOfTheLinkShareIsShown() {
  591. $this->showShareLinkMenuIfNeeded();
  592. $shareLinkMenuTriggerElement = $this->actor->find(self::shareLinkMenuTrigger(), 10);
  593. Assert::assertFalse($this->actor->find(self::hideDownloadCheckboxInput($shareLinkMenuTriggerElement), 10)->isChecked());
  594. }
  595. /**
  596. * @Then I see that the password protect is disabled while loading
  597. */
  598. public function iSeeThatThePasswordProtectIsDisabledWhileLoading() {
  599. // Due to the additional time needed to find the menu trigger element it
  600. // could happen that the request to modify the password protect was
  601. // completed and the field enabled again even before finding the
  602. // disabled field started. Therefore, if the disabled field could not be
  603. // found it is just assumed that it was already enabled again.
  604. // Nevertheless, this check should be done anyway to ensure that the
  605. // following scenario steps are not executed before the request to the
  606. // server was done.
  607. $shareLinkMenuTriggerElement = $this->actor->find(self::shareLinkMenuTrigger(), 10);
  608. try {
  609. $this->actor->find(self::disabledPasswordProtectField($shareLinkMenuTriggerElement), 5);
  610. } catch (NoSuchElementException $exception) {
  611. echo "The password protect field was not found disabled after " . (5 * $this->actor->getFindTimeoutMultiplier()) . " seconds, assumming that it was disabled and enabled again before the check started and continuing";
  612. return;
  613. }
  614. if (!WaitFor::elementToBeEventuallyNotShown(
  615. $this->actor,
  616. self::disabledPasswordProtectField($shareLinkMenuTriggerElement),
  617. $timeout = 10 * $this->actor->getFindTimeoutMultiplier())) {
  618. Assert::fail("The password protect field is still disabled after $timeout seconds");
  619. }
  620. }
  621. /**
  622. * @Then I see that the link share is password protected
  623. */
  624. public function iSeeThatTheLinkShareIsPasswordProtected() {
  625. $this->showShareLinkMenuIfNeeded();
  626. $shareLinkMenuTriggerElement = $this->actor->find(self::shareLinkMenuTrigger(), 10);
  627. Assert::assertTrue($this->actor->find(self::passwordProtectCheckboxInput($shareLinkMenuTriggerElement), 10)->isChecked(), "Password protect checkbox is checked");
  628. Assert::assertTrue($this->actor->find(self::passwordProtectField($shareLinkMenuTriggerElement), 10)->isVisible(), "Password protect field is visible");
  629. }
  630. /**
  631. * @Then I see that the password of the link share is protected by Talk
  632. */
  633. public function iSeeThatThePasswordOfTheLinkShareIsProtectedByTalk() {
  634. $this->showShareLinkMenuIfNeeded();
  635. $shareLinkMenuTriggerElement = $this->actor->find(self::shareLinkMenuTrigger(), 10);
  636. Assert::assertTrue($this->actor->find(self::passwordProtectByTalkCheckboxInput($shareLinkMenuTriggerElement), 10)->isChecked());
  637. }
  638. /**
  639. * @Then I see that the password of the link share is not protected by Talk
  640. */
  641. public function iSeeThatThePasswordOfTheLinkShareIsNotProtectedByTalk() {
  642. $this->showShareLinkMenuIfNeeded();
  643. $shareLinkMenuTriggerElement = $this->actor->find(self::shareLinkMenuTrigger(), 10);
  644. Assert::assertFalse($this->actor->find(self::passwordProtectByTalkCheckboxInput($shareLinkMenuTriggerElement), 10)->isChecked());
  645. }
  646. /**
  647. * @Then I see that the checkbox to protect the password of the link share by Talk is not shown
  648. */
  649. public function iSeeThatTheCheckboxToProtectThePasswordOfTheLinkShareByTalkIsNotShown() {
  650. $this->showShareLinkMenuIfNeeded();
  651. $shareLinkMenuTriggerElement = $this->actor->find(self::shareLinkMenuTrigger(), 10);
  652. try {
  653. Assert::assertFalse(
  654. $this->actor->find(self::passwordProtectByTalkCheckbox($shareLinkMenuTriggerElement))->isVisible());
  655. } catch (NoSuchElementException $exception) {
  656. }
  657. }
  658. /**
  659. * @Given I share the link for :fileName protected by the password :password
  660. */
  661. public function iShareTheLinkForProtectedByThePassword($fileName, $password) {
  662. $this->iShareTheLinkFor($fileName);
  663. $this->iProtectTheSharedLinkWithThePassword($password);
  664. $this->iSeeThatThePasswordProtectIsDisabledWhileLoading();
  665. }
  666. private function showShareLinkMenuIfNeeded() {
  667. $shareLinkMenuTriggerElement = $this->actor->find(self::shareLinkMenuTrigger(), 2);
  668. // In some cases the share menu is hidden after clicking on an action of
  669. // the menu. Therefore, if the menu is visible, wait a little just in
  670. // case it is in the process of being hidden due to a previous action,
  671. // in which case it is shown again.
  672. if (WaitFor::elementToBeEventuallyNotShown(
  673. $this->actor,
  674. self::shareLinkMenu($shareLinkMenuTriggerElement),
  675. $timeout = 2 * $this->actor->getFindTimeoutMultiplier())) {
  676. $this->actor->find(self::shareLinkMenuButton(), 10)->click();
  677. }
  678. }
  679. private function showShareWithMenuIfNeeded($shareWithName) {
  680. $shareWithMenuTriggerElement = $this->actor->find(self::shareWithMenuTrigger($shareWithName), 2);
  681. // In some cases the share menu is hidden after clicking on an action of
  682. // the menu. Therefore, if the menu is visible, wait a little just in
  683. // case it is in the process of being hidden due to a previous action,
  684. // in which case it is shown again.
  685. if (WaitFor::elementToBeEventuallyNotShown(
  686. $this->actor,
  687. self::shareWithMenu($shareWithName, $shareWithMenuTriggerElement),
  688. $timeout = 2 * $this->actor->getFindTimeoutMultiplier())) {
  689. $this->actor->find(self::shareWithMenuButton($shareWithName), 10)->click();
  690. }
  691. }
  692. }