diff --git a/src/main/java/org/olat/modules/portfolio/ui/AbstractPageListController.java b/src/main/java/org/olat/modules/portfolio/ui/AbstractPageListController.java index ad540502c53f31114cfb7fe1b45df8eecbcd5912..675434aa2155659d840364def41d5946042fa18c 100644 --- a/src/main/java/org/olat/modules/portfolio/ui/AbstractPageListController.java +++ b/src/main/java/org/olat/modules/portfolio/ui/AbstractPageListController.java @@ -501,10 +501,13 @@ implements Activateable2, TooledController, FlexiTableComponentDelegate { if(event == Event.CHANGED_EVENT) { loadModel(ureq, null); fireEvent(ureq, Event.CHANGED_EVENT); - } else if(event instanceof PageRemovedEvent || event instanceof PageDeletedEvent) { + } else if(event instanceof PageRemovedEvent) { loadModel(ureq, null); stackPanel.popUpToController(this); fireEvent(ureq, Event.CHANGED_EVENT); + } else if(event instanceof PageDeletedEvent) { + loadModel(ureq, null); + fireEvent(ureq, event); } } else if(commentsCtrl == source) { if(event == Event.CHANGED_EVENT || "comment_count_changed".equals(event.getCommand())) { diff --git a/src/main/java/org/olat/modules/portfolio/ui/BinderListController.java b/src/main/java/org/olat/modules/portfolio/ui/BinderListController.java index 7ae58183a5c2f825aae5b414790320c5ec696246..752c72403677dc59ecee65ddf605e29f543088d7 100644 --- a/src/main/java/org/olat/modules/portfolio/ui/BinderListController.java +++ b/src/main/java/org/olat/modules/portfolio/ui/BinderListController.java @@ -45,6 +45,7 @@ import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTable import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableComponentDelegate; import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableDataModelFactory; import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableRendererType; +import org.olat.core.gui.components.form.flexible.impl.elements.table.SelectionEvent; import org.olat.core.gui.components.link.Link; import org.olat.core.gui.components.link.LinkFactory; import org.olat.core.gui.components.stack.TooledController; @@ -349,6 +350,18 @@ public class BinderListController extends FormBasicController doNewBinderCallout(ureq); } else if(newBinderFromCourseButton == source) { doNewBinderFromCourse(ureq); + } else if(tableEl == source) { + if(event instanceof SelectionEvent) { + SelectionEvent se = (SelectionEvent)event; + String cmd = se.getCommand(); + if("select".equals(cmd)) { + BinderRow row = model.getObject(se.getIndex()); + Activateable2 activateable = doOpenBinder(ureq, row); + if(activateable != null) { + activateable.activate(ureq, null, null); + } + } + } } else if(source instanceof FormLink) { FormLink link = (FormLink)source; String cmd = link.getCmd(); diff --git a/src/main/java/org/olat/modules/portfolio/ui/PageRunController.java b/src/main/java/org/olat/modules/portfolio/ui/PageRunController.java index 7a8d90215722841e4167a522167af3fbdf48b866..f1bf0c7eadadb58190d0bec47de3770a04f5270d 100644 --- a/src/main/java/org/olat/modules/portfolio/ui/PageRunController.java +++ b/src/main/java/org/olat/modules/portfolio/ui/PageRunController.java @@ -153,6 +153,7 @@ public class PageRunController extends BasicController implements TooledControll moveToTrashLink = LinkFactory.createToolLink("delete.page", translate("delete.page"), this); moveToTrashLink.setIconLeftCSS("o_icon o_icon-lg o_icon_delete_item"); + moveToTrashLink.setElementCssClass("o_sel_pf_move_page_to_trash"); moveToTrashLink.setVisible(secCallback.canDeletePage(page)); stackPanel.addTool(moveToTrashLink, Align.right); @@ -163,6 +164,7 @@ public class PageRunController extends BasicController implements TooledControll deleteLink = LinkFactory.createToolLink("delete.def.page", translate("delete.def.page"), this); deleteLink.setIconLeftCSS("o_icon o_icon-lg o_icon_delete_item"); + deleteLink.setElementCssClass("o_sel_pf_delete_page"); stackPanel.addTool(deleteLink, Align.left); } } diff --git a/src/main/java/org/olat/modules/portfolio/ui/RestorePageController.java b/src/main/java/org/olat/modules/portfolio/ui/RestorePageController.java index 3a61a50e50c4caa2ae3a54003044e5fb82c8e22e..d0ed978cba332eb5caef7d2ed7e78dace59c70e2 100644 --- a/src/main/java/org/olat/modules/portfolio/ui/RestorePageController.java +++ b/src/main/java/org/olat/modules/portfolio/ui/RestorePageController.java @@ -130,7 +130,7 @@ public class RestorePageController extends FormBasicController { for (int i = 0; i < numOfSections; i++) { Long sectionKey = sections.get(i).getKey(); theKeys[i] = sectionKey.toString(); - theValues[i] = (i + 1) + ". " + sections.get(i).getTitle(); + theValues[i] = sections.get(i).getTitle(); } sectionsEl.setKeysAndValues(theKeys, theValues, null); diff --git a/src/main/java/org/olat/modules/portfolio/ui/TrashController.java b/src/main/java/org/olat/modules/portfolio/ui/TrashController.java index 2e73edc948c2c5103521fd69731251f07a58f8e5..018ae1b7e115c82ff1e9f6bfaef2ba7966ceb6e2 100644 --- a/src/main/java/org/olat/modules/portfolio/ui/TrashController.java +++ b/src/main/java/org/olat/modules/portfolio/ui/TrashController.java @@ -34,6 +34,7 @@ import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.controller.BasicController; import org.olat.modules.portfolio.BinderSecurityCallback; import org.olat.modules.portfolio.ui.event.DeleteBinderEvent; +import org.olat.modules.portfolio.ui.event.PageDeletedEvent; import org.olat.modules.portfolio.ui.event.RestoreBinderEvent; /** @@ -95,9 +96,11 @@ public class TrashController extends BasicController { @Override protected void event(UserRequest ureq, Controller source, Event event) { - if(event instanceof RestoreBinderEvent || event instanceof DeleteBinderEvent) { + if(event instanceof RestoreBinderEvent + || event instanceof DeleteBinderEvent + || event instanceof PageDeletedEvent) { stackPanel.popUpToController(this); - } + } super.event(ureq, source, event); } diff --git a/src/test/java/org/olat/selenium/PortfolioV2Test.java b/src/test/java/org/olat/selenium/PortfolioV2Test.java index d1ef393740c0e50277d16d2e6cdf7ed811567dd3..f32a5f59ffd3b6306746088de0e1f6fdb9187961 100644 --- a/src/test/java/org/olat/selenium/PortfolioV2Test.java +++ b/src/test/java/org/olat/selenium/PortfolioV2Test.java @@ -49,6 +49,8 @@ import org.olat.selenium.page.forum.ForumPage; import org.olat.selenium.page.graphene.OOGraphene; import org.olat.selenium.page.portfolio.BinderPage; import org.olat.selenium.page.portfolio.BinderPublicationPage; +import org.olat.selenium.page.portfolio.BindersPage; +import org.olat.selenium.page.portfolio.EntriesPage; import org.olat.selenium.page.portfolio.EntryPage; import org.olat.selenium.page.portfolio.MediaCenterPage; import org.olat.selenium.page.portfolio.PortfolioV2HomePage; @@ -838,4 +840,170 @@ public class PortfolioV2Test { .assertOnDocument(pdfFile) .assertOnCitation(citation); } + + + /** + * A user create a binder with a section and two pages. It deletes + * one, go to the trash, find the delete page, restore it and go + * again in the binder. It move a second time the page to the trash + * and delete it definitively. + * + * @param loginPage + * @throws IOException + * @throws URISyntaxException + */ + @Test + @RunAsClient + public void deletePage(@InitialPage LoginPage loginPage) + throws IOException, URISyntaxException { + UserVO author = new UserRestClient(deploymentUrl).createRandomUser("rei"); + + loginPage + .loginAs(author.getLogin(), author.getPassword()) + .resume(); + + UserToolsPage userTools = new UserToolsPage(browser); + PortfolioV2HomePage portfolio = userTools + .openUserToolsMenu() + .openPortfolioV2(); + + String binderTitle = "Binder del " + UUID.randomUUID(); + BinderPage binder = portfolio + .openMyBinders() + .createBinder(binderTitle, "A binder where I want to delete some pages"); + + String sectionTitle = "Section one " + UUID.randomUUID(); + binder + .selectEntries() + .createSection(sectionTitle) + .assertOnSectionTitleInEntries(sectionTitle); + + String pageTitle = "Page two " + UUID.randomUUID(); + String pageToDelete = "Page del " + UUID.randomUUID(); + binder + .createEntry(pageToDelete) + .assertOnPage(pageToDelete) + .selectEntries() + .createEntry(pageTitle) + .assertOnPage(pageTitle) + .selectTableOfContent() + .selectEntryInToc(pageToDelete) + .moveEntryToTrash() + .assertOnPageInToc(pageTitle) + .assertOnPageNotInToc(pageToDelete); + + EntriesPage trash = portfolio + .clickToolbarBack() + .clickToolbarBack() + .openDeletedEntries(); + + trash + .assertOnPage(pageToDelete) + .switchTableView() + .restore(pageToDelete, binderTitle, sectionTitle); + + portfolio + .clickToolbarBack() + .openMyBinders() + .selectBinder(binderTitle) + .assertOnPageInToc(pageToDelete) + .selectEntryInToc(pageToDelete) + .moveEntryToTrash(); + + trash = portfolio + .clickToolbarBack() + .clickToolbarBack() + .openDeletedEntries(); + + trash + .assertOnPageTableView(pageToDelete) + .switchTableView() + .selectPageInTableView(pageToDelete) + .deleteEntry() + .assertEmptyTableView(); + } + + /** + * A user create a binder with section and pages, move it to + * the trash. Then it goes to the trash restore it. Return to + * the list of binders, move the binder again to the trash and + * goes there to delete it definitively. + * + * @param loginPage + * @throws IOException + * @throws URISyntaxException + */ + @Test + @RunAsClient + public void deleteBinder(@InitialPage LoginPage loginPage) + throws IOException, URISyntaxException { + UserVO author = new UserRestClient(deploymentUrl).createRandomUser("rei"); + + loginPage + .loginAs(author.getLogin(), author.getPassword()) + .resume(); + + UserToolsPage userTools = new UserToolsPage(browser); + PortfolioV2HomePage portfolio = userTools + .openUserToolsMenu() + .openPortfolioV2(); + + String binderTitle = "Binder ephemere " + UUID.randomUUID(); + BindersPage myBinders = portfolio + .openMyBinders(); + BinderPage binder = myBinders + .createBinder(binderTitle, "A binder that I want to delete"); + + String sectionTitle = "Section one " + UUID.randomUUID(); + binder + .selectEntries() + .createSection(sectionTitle) + .assertOnSectionTitleInEntries(sectionTitle); + + for(int i=1; i<3; i++) { + String pageTitle = "Page " + i; + binder + .createEntry(pageTitle) + .assertOnPage(pageTitle) + .selectEntries(); + } + binder + .selectTableOfContent() + .selectEntryInToc("Page 1"); + + //reload the binder + portfolio + .clickToolbarBack() + .clickToolbarBack(); + myBinders + .selectBinder(binderTitle); + + // move the binder to the trash + binder + .assertOnPageInToc("Page 1") + .moveBinderToTrash(); + + // go in the trash to restore it + portfolio + .clickToolbarBack() + .openDeletedBinders() + .switchTableView() + .restoreBinder(binderTitle); + + // move it to the trash again + portfolio + .clickToolbarBack() + .openMyBinders() + .selectBinder(binderTitle) + .moveBinderToTrash(); + + // go to the trash to delete it definitively + portfolio + .clickToolbarBack() + .openDeletedBinders() + .selectBinderInTableView(binderTitle) + .assertOnPageInToc("Page 2") + .deleteBinder() + .assertEmptyTableView(); + } } diff --git a/src/test/java/org/olat/selenium/page/portfolio/BinderPage.java b/src/test/java/org/olat/selenium/page/portfolio/BinderPage.java index ec5aea89ac10b6fa995077a5504d6d58a61e1018..310c6057e92aadb49024f91821df927d089be405 100644 --- a/src/test/java/org/olat/selenium/page/portfolio/BinderPage.java +++ b/src/test/java/org/olat/selenium/page/portfolio/BinderPage.java @@ -65,8 +65,22 @@ public class BinderPage { } public BinderPage assertOnPageInToc(String title) { - By sectionTitleBy = By.xpath("//a[contains(@class,'o_pf_open_entry')]/span[contains(text(),'" + title + "')]"); - OOGraphene.waitElement(sectionTitleBy, 5, browser); + By pageTitleBy = By.xpath("//a[contains(@class,'o_pf_open_entry')]/span[contains(text(),'" + title + "')]"); + OOGraphene.waitElement(pageTitleBy, 5, browser); + return this; + } + + /** + * Make sure the table of content is loaded. The method + * check if the number of pages with this title is zero. + * + * @param title + * @return + */ + public BinderPage assertOnPageNotInToc(String title) { + By pageTitleBy = By.xpath("//a[contains(@class,'o_pf_open_entry')]/span[contains(text(),'" + title + "')]"); + List<WebElement> pageEls = browser.findElements(pageTitleBy); + Assert.assertTrue(pageEls.isEmpty()); return this; } @@ -99,6 +113,42 @@ public class BinderPage { return this; } + public BindersPage moveBinderToTrash() { + By deleteBy = By.xpath("//li[contains(@class,'o_tool')]/a[contains(@onclick,'delete.binder')]"); + OOGraphene.waitElement(deleteBy, 5, browser); + browser.findElement(deleteBy).click(); + OOGraphene.waitBusy(browser); + + //confirm check box + By confirmBoxBy = By.cssSelector("div.modal-body input[type='checkbox']"); + WebElement confirmBoxEl = browser.findElement(confirmBoxBy); + OOGraphene.check(confirmBoxEl, Boolean.TRUE); + + By deleteButtonBy = By.cssSelector("div.modal-body div.o_button_group button.btn.btn-primary"); + browser.findElement(deleteButtonBy).click(); + OOGraphene.waitAndCloseBlueMessageWindow(browser); + return new BindersPage(browser); + } + + public BindersPage deleteBinder() { + By deleteBy = By.xpath("//li[contains(@class,'o_tool')]/a[contains(@onclick,'delete.binder')]"); + OOGraphene.waitElement(deleteBy, 5, browser); + browser.findElement(deleteBy).click(); + OOGraphene.waitBusy(browser); + + //confirm check box + By confirmBoxBy = By.cssSelector("div.modal-body input[type='checkbox']"); + List<WebElement> confirmBoxEls = browser.findElements(confirmBoxBy); + for(WebElement confirmBoxEl:confirmBoxEls) { + OOGraphene.check(confirmBoxEl, Boolean.TRUE); + } + + By deleteButtonBy = By.cssSelector("div.modal-body div.o_button_group button.btn.btn-primary"); + browser.findElement(deleteButtonBy).click(); + OOGraphene.waitAndCloseBlueMessageWindow(browser); + return new BindersPage(browser); + } + /** * Select the table of content segment of the navigation * @return Itself @@ -295,7 +345,7 @@ public class BinderPage { /** * Yes in a dialog box controller. */ - private void confirm() { + protected void confirm() { By confirmButtonBy = By.xpath("//div[contains(@class,'modal-dialo')]//div[contains(@class,'modal-footer')]/a[contains(@onclick,'link_0')]"); OOGraphene.waitElement(confirmButtonBy, 5, browser); OOGraphene.waitScrollTop(browser); diff --git a/src/test/java/org/olat/selenium/page/portfolio/BindersPage.java b/src/test/java/org/olat/selenium/page/portfolio/BindersPage.java index 089ea3b867af52aaf9f3bf9476eaf9af6b26036a..69b0dc310d2d14aef59c0d88a13e54f608b723a8 100644 --- a/src/test/java/org/olat/selenium/page/portfolio/BindersPage.java +++ b/src/test/java/org/olat/selenium/page/portfolio/BindersPage.java @@ -65,4 +65,51 @@ public class BindersPage { OOGraphene.waitElement(contentBy, 5, browser); return new BinderPage(browser); } + + public BinderPage selectBinder(String title) { + By binderBy = By.xpath("//div[contains(@class,'o_binder')][div/h4[contains(text(),'" + title + "')]]//div[contains(@class,'pull-right')]/a"); + browser.findElement(binderBy).click(); + OOGraphene.waitBusy(browser); + return new BinderPage(browser); + } + + public BindersPage switchTableView() { + By tableViewBy = By.xpath("//a[i[contains(@class,'o_icon o_icon_table o_icon-lg')]]"); + browser.findElement(tableViewBy).click(); + OOGraphene.waitBusy(browser); + + By classicViewBy = By.cssSelector(".o_rendertype_classic"); + OOGraphene.waitElement(classicViewBy, 5, browser); + return this; + } + + /** + * Only check the presence of the message "table empty". + * + * @return + */ + public BindersPage assertEmptyTableView() { + By emptyMessageBy = By.cssSelector("div.o_segments_content div.o_info"); + OOGraphene.waitElement(emptyMessageBy, 5, browser); + return this; + } + + public BinderPage selectBinderInTableView(String title) { + By binderBy = By.xpath("//table//tr/td/a[contains(text(),'" + title + "')]"); + browser.findElement(binderBy).click(); + OOGraphene.waitBusy(browser); + return new BinderPage(browser); + } + + public BindersPage restoreBinder(String title) { + By restoreBy = By.xpath("//table//tr[td/a[contains(text(),'" + title + "')]]/td/a[contains(@href,'restore')]"); + browser.findElement(restoreBy).click(); + OOGraphene.waitBusy(browser); + + By confirmButtonBy = By.xpath("//div[contains(@class,'modal-dialo')]//div[contains(@class,'modal-footer')]/a[contains(@onclick,'link_0')]"); + OOGraphene.waitElement(confirmButtonBy, 5, browser); + browser.findElement(confirmButtonBy).click(); + OOGraphene.waitAndCloseBlueMessageWindow(browser); + return this; + } } diff --git a/src/test/java/org/olat/selenium/page/portfolio/EntriesPage.java b/src/test/java/org/olat/selenium/page/portfolio/EntriesPage.java index b68ebcc223bf71688f0f212d0ea2466577d18916..b6b554328fd7c094bb4358d525e9a0a1d7d8a5fa 100644 --- a/src/test/java/org/olat/selenium/page/portfolio/EntriesPage.java +++ b/src/test/java/org/olat/selenium/page/portfolio/EntriesPage.java @@ -19,10 +19,14 @@ */ package org.olat.selenium.page.portfolio; +import java.util.List; + +import org.junit.Assert; import org.olat.selenium.page.graphene.OOGraphene; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.ui.Select; /** * @@ -61,4 +65,61 @@ public class EntriesPage { return new EntryPage(browser); } + public EntryPage selectPageInTableView(String title) { + By selectBy = By.xpath("//div[contains(@class,'o_binder_page_listing')]/table//a/span[contains(@class,'o_pf_page')][contains(text(),'" + title + "')]"); + browser.findElement(selectBy).click(); + OOGraphene.waitBusy(browser); + return new EntryPage(browser); + } + + public EntriesPage assertOnPage(String title) { + By pageTitleBy = By.xpath("//div[contains(@class,'o_portfolio_page')]/div/h4[contains(text(),'" + title + "')]"); + List<WebElement> pageTitleEls = browser.findElements(pageTitleBy); + Assert.assertEquals(1, pageTitleEls.size()); + return this; + } + + public EntriesPage assertOnPageTableView(String title) { + By pageTitleBy = By.xpath("//div[contains(@class,'o_binder_page_listing')]/table//a/span[contains(text(),'" + title + "')]"); + OOGraphene.waitElement(pageTitleBy, 5, browser); + List<WebElement> pageTitleEls = browser.findElements(pageTitleBy); + Assert.assertEquals(1, pageTitleEls.size()); + return this; + } + + public EntriesPage switchTableView() { + By tableViewBy = By.xpath("//a[i[contains(@class,'o_icon o_icon_table o_icon-lg')]]"); + browser.findElement(tableViewBy).click(); + OOGraphene.waitBusy(browser); + + By classicViewBy = By.cssSelector(".o_rendertype_classic"); + OOGraphene.waitElement(classicViewBy, 5, browser); + return this; + } + + public EntriesPage assertEmptyTableView() { + By emptyMessageBy = By.cssSelector("div.o_portfolio_entries div.o_info"); + OOGraphene.waitElement(emptyMessageBy, 5, browser); + return this; + } + + public EntriesPage restore(String title, String binder, String section) { + By restoreBy = By.xpath("//table//tr[td/a/span[contains(text(),'" + title + "')]]/td/a[contains(@href,'restore')]"); + browser.findElement(restoreBy).click(); + OOGraphene.waitBusy(browser); + + By selectBinderBy = By.cssSelector("#o_cobinders_SELBOX select"); + WebElement selectBinderEl = browser.findElement(selectBinderBy); + new Select(selectBinderEl).selectByVisibleText(binder); + + By selectSectionBy = By.cssSelector("#o_cosections_SELBOX select"); + WebElement selectSectionEl = browser.findElement(selectSectionBy); + new Select(selectSectionEl).selectByVisibleText(section); + + By restoreButtonBy = By.cssSelector("div.modal-dialog button"); + browser.findElement(restoreButtonBy).click(); + OOGraphene.waitBusy(browser); + return this; + } + } diff --git a/src/test/java/org/olat/selenium/page/portfolio/EntryPage.java b/src/test/java/org/olat/selenium/page/portfolio/EntryPage.java index 0e28fa18bbf4d8410158841251444225aebc8e2d..78b42b8ba9471c9fe71c86525a80c0ca723080f0 100644 --- a/src/test/java/org/olat/selenium/page/portfolio/EntryPage.java +++ b/src/test/java/org/olat/selenium/page/portfolio/EntryPage.java @@ -173,6 +173,29 @@ public class EntryPage { return this; } + public BinderPage moveEntryToTrash() { + By moveToTrashBy = By.cssSelector("a.o_sel_pf_move_page_to_trash"); + OOGraphene.waitElement(moveToTrashBy, 5, browser); + browser.findElement(moveToTrashBy).click(); + OOGraphene.waitBusy(browser); + OOGraphene.waitModalDialog(browser); + + BinderPage binder = new BinderPage(browser); + binder.confirm(); + return binder; + } + + public EntriesPage deleteEntry() { + By moveToTrashBy = By.cssSelector("a.o_sel_pf_delete_page"); + OOGraphene.waitElement(moveToTrashBy, 5, browser); + browser.findElement(moveToTrashBy).click(); + OOGraphene.waitBusy(browser); + OOGraphene.waitModalDialog(browser); + + new BinderPage(browser).confirm(); + return new EntriesPage(browser); + } + public EntryPage toggleEditor() { By closeBy = By.cssSelector("a.o_sel_pf_edit_page"); OOGraphene.waitElement(closeBy, 5, browser); diff --git a/src/test/java/org/olat/selenium/page/portfolio/PortfolioV2HomePage.java b/src/test/java/org/olat/selenium/page/portfolio/PortfolioV2HomePage.java index 19b4d5d8a88bdd85cbba12a2569afce8a8a2f9bf..b709d1a85e28a8edeb45d53d95f52bc04a39a6d0 100644 --- a/src/test/java/org/olat/selenium/page/portfolio/PortfolioV2HomePage.java +++ b/src/test/java/org/olat/selenium/page/portfolio/PortfolioV2HomePage.java @@ -89,4 +89,29 @@ public class PortfolioV2HomePage { OOGraphene.waitElement(myEntriesBy, 5, browser); return new EntriesPage(browser); } + + public EntriesPage openDeletedEntries() { + By goToTrashBy = By.xpath("//div[contains(@class,'o_button_group')]//a[contains(@onclick,'go.to.trash')]"); + OOGraphene.waitElement(goToTrashBy, 5, browser); + browser.findElement(goToTrashBy).click(); + OOGraphene.waitBusy(browser); + return new EntriesPage(browser); + } + + public BindersPage openDeletedBinders() { + openDeletedEntries(); + + By deletedBindersBy = By.xpath("//div[contains(@class,'o_segments')]//a[contains(@onclick,'binders')]"); + OOGraphene.waitElement(deletedBindersBy, 5, browser); + browser.findElement(deletedBindersBy).click(); + OOGraphene.waitBusy(browser); + return new BindersPage(browser); + } + + public PortfolioV2HomePage clickToolbarBack() { + By toolbarBackBy = By.cssSelector("li.o_breadcrumb_back>a"); + browser.findElement(toolbarBackBy).click(); + OOGraphene.waitBusy(browser); + return assertHome(); + } }