FilesAppSharingContext.php 31 KB

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