From 9e6e00ee6e9d92a785980cd294b8e67bc652451a Mon Sep 17 00:00:00 2001 From: srosse <none@none> Date: Tue, 21 Jul 2015 20:51:38 +0200 Subject: [PATCH] no-jira: selenium test for course with a password protected structure element --- .../condition/_content/defaultaccessedit.html | 2 +- .../PasswordConditionEditController.java | 2 + .../PasswordVerificationController.java | 2 + .../course/editor/EditorMainController.java | 2 + .../java/org/olat/selenium/CourseTest.java | 122 ++++++++++++++++++ .../page/course/CourseEditorPageFragment.java | 86 ++++++++++++ .../page/course/CoursePageFragment.java | 21 +++ 7 files changed, 236 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/olat/course/condition/_content/defaultaccessedit.html b/src/main/java/org/olat/course/condition/_content/defaultaccessedit.html index 939f4590fff..1981979ba8c 100644 --- a/src/main/java/org/olat/course/condition/_content/defaultaccessedit.html +++ b/src/main/java/org/olat/course/condition/_content/defaultaccessedit.html @@ -4,7 +4,7 @@ $r.render("defaultAccessConditionView") </fieldset> #if($renderPW) - <fieldset> + <fieldset class="o_sel_course_node_password_config"> <legend>$r.contextHelpWithWrapper("org.olat.course.condition.additionalconditions","ced-password.html","help.hover.password") $r.translate("password.field")</legend> $r.render("pwcond") diff --git a/src/main/java/org/olat/course/condition/additionalconditions/PasswordConditionEditController.java b/src/main/java/org/olat/course/condition/additionalconditions/PasswordConditionEditController.java index 7e679706751..f1f9c36a246 100644 --- a/src/main/java/org/olat/course/condition/additionalconditions/PasswordConditionEditController.java +++ b/src/main/java/org/olat/course/condition/additionalconditions/PasswordConditionEditController.java @@ -58,9 +58,11 @@ public class PasswordConditionEditController extends FormBasicController { protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { passwordSwitch = uifactory.addCheckboxesHorizontal("password.field", "password.field", formLayout, new String[]{"ison"}, new String[]{ "" }); passwordSwitch.addActionListener(FormEvent.ONCHANGE); + passwordSwitch.setElementCssClass("o_sel_course_password_condition_switch"); passwordField = uifactory.addTextElement("passwordField", null, 30, "", formLayout); passwordField.setExampleKey("password.example", null); + passwordField.setElementCssClass("o_sel_course_password_condition_value"); passwordField.showError(false); if (condition != null && StringHelper.containsNonWhitespace(condition.getPassword())) { passwordSwitch.select("ison", true); diff --git a/src/main/java/org/olat/course/condition/additionalconditions/PasswordVerificationController.java b/src/main/java/org/olat/course/condition/additionalconditions/PasswordVerificationController.java index 0ce78f44d06..2964b84eb6b 100644 --- a/src/main/java/org/olat/course/condition/additionalconditions/PasswordVerificationController.java +++ b/src/main/java/org/olat/course/condition/additionalconditions/PasswordVerificationController.java @@ -58,8 +58,10 @@ public class PasswordVerificationController extends FormBasicController { protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { setFormTitle("password.title"); setFormWarning("password.inputorder"); + formLayout.setElementCssClass("o_sel_course_password_form"); pwElement = uifactory.addPasswordElement("password.field", "password.field", 255, "", formLayout); + pwElement.setElementCssClass("o_sel_course_password"); pwElement.setMandatory(true); pwElement.setDisplaySize(30); diff --git a/src/main/java/org/olat/course/editor/EditorMainController.java b/src/main/java/org/olat/course/editor/EditorMainController.java index 848e133b72b..cce7aced7b5 100644 --- a/src/main/java/org/olat/course/editor/EditorMainController.java +++ b/src/main/java/org/olat/course/editor/EditorMainController.java @@ -299,10 +299,12 @@ public class EditorMainController extends MainLayoutBasicController implements G nodeTools = new Dropdown("insertNodes", NLS_COMMAND_DELETENODE_HEADER, false, getTranslator()); nodeTools.setIconCSS("o_icon o_icon_customize"); + nodeTools.setElementCssClass("o_sel_course_editor_change_node"); deleteNodeLink = LinkFactory.createToolLink(CMD_DELNODE, translate(NLS_COMMAND_DELETENODE), this, "o_icon_delete_item"); nodeTools.addComponent(deleteNodeLink); moveNodeLink = LinkFactory.createToolLink(CMD_MOVENODE, translate(NLS_COMMAND_MOVENODE), this, "o_icon_move"); + moveNodeLink.setElementCssClass("o_sel_course_editor_move_node"); nodeTools.addComponent(moveNodeLink); copyNodeLink = LinkFactory.createToolLink(CMD_COPYNODE, translate(NLS_COMMAND_COPYNODE), this, "o_icon_copy"); nodeTools.addComponent(copyNodeLink); diff --git a/src/test/java/org/olat/selenium/CourseTest.java b/src/test/java/org/olat/selenium/CourseTest.java index 1ec30ac5263..3f8d2719188 100644 --- a/src/test/java/org/olat/selenium/CourseTest.java +++ b/src/test/java/org/olat/selenium/CourseTest.java @@ -45,6 +45,7 @@ import org.olat.selenium.page.NavigationPage; import org.olat.selenium.page.Participant; import org.olat.selenium.page.User; import org.olat.selenium.page.core.BookingPage; +import org.olat.selenium.page.core.MenuTreePageFragment; import org.olat.selenium.page.course.CourseEditorPageFragment; import org.olat.selenium.page.course.CoursePageFragment; import org.olat.selenium.page.course.CourseWizardPage; @@ -1006,4 +1007,125 @@ public class CourseTest { .assertLogList(kanu, reminderTitle, true) .assertLogList(author, reminderTitle, false); } + + /** + * An author creates a course with a structure element. The structure + * element is password protected. Under it, there is an info node. The + * course is published and a first user search the course, go to the + * structure element, give the password and see the info node. A second + * user grabs the rest url of the structure node, use it, give the password + * and go to the info node. + * + * @param loginPage + * @throws IOException + * @throws URISyntaxException + */ + @Test + @RunAsClient + public void coursePassword(@InitialPage LoginPage loginPage, + @Drone @Participant WebDriver kanuBrowser, + @Drone @User WebDriver ryomouBrowser) + throws IOException, URISyntaxException { + UserVO author = new UserRestClient(deploymentUrl).createAuthor(); + UserVO kanu = new UserRestClient(deploymentUrl).createRandomUser("Kanu"); + UserVO ryomou = new UserRestClient(deploymentUrl).createRandomUser("Ryomou"); + loginPage.loginAs(author.getLogin(), author.getPassword()); + + //go to authoring + AuthoringEnvPage authoringEnv = navBar + .assertOnNavigationPage() + .openAuthoringEnvironment(); + + String title = "Password-me-" + UUID.randomUUID(); + //create course + authoringEnv + .openCreateDropDown() + .clickCreate(ResourceType.course) + .fillCreateForm(title) + .assertOnGeneralTab() + .save(); + + String infoTitle = "Info - " + UUID.randomUUID(); + String structureTitle = "St - " + UUID.randomUUID(); + + //open course editor, create a structure node + CoursePageFragment course = new CoursePageFragment(browser); + CourseEditorPageFragment editor = course + .openToolsMenu() + .edit(); + editor + .createNode("st") + .nodeTitle(structureTitle); + String courseInfoUrl = editor.getRestUrl(); + editor + //create an info node and move it under the structure node + .createNode("info") + .nodeTitle(infoTitle) + .moveUnder(structureTitle) + .selectNode(structureTitle) + //select and set password on structure node + .selectTabPassword() + .setPassword("super secret") + //publish + .autoPublish() + .accessConfiguration() + .setUserAccess(UserAccess.registred) + .clickToolbarBack(); + + MenuTreePageFragment courseTree = course + .clickTree() + .selectWithTitle(structureTitle.substring(0, 20)); + course + .assertOnPassword() + .enterPassword("super secret"); + courseTree + .selectWithTitle(infoTitle.substring(0, 20)); + course + .assertOnTitle(infoTitle); + + //First user go to the course + LoginPage kanuLoginPage = LoginPage.getLoginPage(kanuBrowser, deploymentUrl); + kanuLoginPage + .loginAs(kanu.getLogin(), kanu.getPassword()) + .resume(); + + NavigationPage kanuNavBar = new NavigationPage(kanuBrowser); + kanuNavBar + .openMyCourses() + .openSearch() + .extendedSearch(title) + .select(title) + .start(); + + //go to the structure, give the password + CoursePageFragment kanuCourse = new CoursePageFragment(kanuBrowser); + MenuTreePageFragment kanuTree = kanuCourse + .clickTree() + .selectWithTitle(structureTitle.substring(0, 20)); + kanuCourse + .assertOnPassword() + .enterPassword("super secret"); + kanuTree + .selectWithTitle(infoTitle.substring(0, 20)); + kanuCourse + .assertOnTitle(infoTitle); + + //Second user use the rest url + LoginPage ryomouLoginPage = LoginPage.getLoginPage(ryomouBrowser, new URL(courseInfoUrl)); + ryomouLoginPage + .loginAs(ryomou.getLogin(), ryomou.getPassword()) + .resume(); + + CoursePageFragment ryomouCourse = new CoursePageFragment(ryomouBrowser); + ryomouCourse + .assertOnPassword() + .enterPassword("super secret"); + //find the secret info course element + ryomouCourse + .clickTree() + .selectWithTitle(structureTitle.substring(0, 20)) + .selectWithTitle(infoTitle.substring(0, 20)); + ryomouCourse + .assertOnTitle(infoTitle); + } } diff --git a/src/test/java/org/olat/selenium/page/course/CourseEditorPageFragment.java b/src/test/java/org/olat/selenium/page/course/CourseEditorPageFragment.java index 82ab18128ba..cdd8e6f71e5 100644 --- a/src/test/java/org/olat/selenium/page/course/CourseEditorPageFragment.java +++ b/src/test/java/org/olat/selenium/page/course/CourseEditorPageFragment.java @@ -58,6 +58,9 @@ public class CourseEditorPageFragment { public static final By chooseScormButton = By.className("o_sel_scorm_choose_repofile"); public static final By choosePortfolioButton = By.className("o_sel_map_choose_repofile"); + public static final By changeNodeToolsMenu = By.cssSelector("ul.o_sel_course_editor_change_node"); + public static final By changeNodeToolsMenuCaret = By.cssSelector("a.o_sel_course_editor_change_node"); + public static final List<By> chooseRepoEntriesButtonList = new ArrayList<>(); static { @@ -96,6 +99,29 @@ public class CourseEditorPageFragment { return this; } + /** + * Select the tab where the password setting are + * @return + */ + public CourseEditorPageFragment selectTabPassword() { + By passwordTabBy = By.cssSelector("fieldset.o_sel_course_node_password_config"); + return selectTab(passwordTabBy); + } + + public CourseEditorPageFragment setPassword(String password) { + By switchBy = By.cssSelector(".o_sel_course_password_condition_switch input[type='checkbox']"); + browser.findElement(switchBy).click(); + OOGraphene.waitBusy(browser); + + By passwordBy = By.cssSelector(".o_sel_course_password_condition_value input[type='text']"); + browser.findElement(passwordBy).sendKeys(password); + + By saveBy = By.cssSelector("fieldset.o_sel_course_node_password_config button.btn-primary"); + browser.findElement(saveBy).click(); + OOGraphene.waitBusy(browser); + return this; + } + /** * Select the tab score in a structure node. * @@ -209,6 +235,66 @@ public class CourseEditorPageFragment { return this; } + public String getRestUrl() { + By openerBy = By.cssSelector("a.o_opener"); + browser.findElement(openerBy).click(); + + By urlBy = By.cssSelector("div.o_copy_code"); + OOGraphene.waitElement(urlBy, browser); + + String url = null; + List<WebElement> urlEls = browser.findElements(urlBy); + for(WebElement urlEl:urlEls) { + String text = urlEl.getText(); + if(text.contains("http")) { + url = text.trim(); + break; + } + } + Assert.assertNotNull(url); + return url; + } + + public CourseEditorPageFragment moveUnder(String targetNodeTitle) { + if(!browser.findElement(changeNodeToolsMenu).isDisplayed()) { + openChangeNodeToolsMenu(); + } + By changeNodeLinkBy = By.cssSelector("a.o_sel_course_editor_move_node"); + browser.findElement(changeNodeLinkBy).click(); + OOGraphene.waitBusy(browser); + + By targetNodeBy = By.xpath("//div[contains(@class,'o_tree_insert_tool')]//a[contains(@title,'" + targetNodeTitle + "')]"); + browser.findElement(targetNodeBy).click(); + OOGraphene.waitBusy(browser); + + By underBy = By.xpath("//div[contains(@class,'o_tree_insert_tool')]//a[i[contains(@class,'o_icon_node_under')]]"); + browser.findElement(underBy).click(); + OOGraphene.waitBusy(browser); + + By saveBy = By.cssSelector("div.modal-content div.o_button_group a.btn-primary"); + browser.findElement(saveBy).click(); + OOGraphene.waitBusy(browser); + OOGraphene.waitAndCloseBlueMessageWindow(browser); + return this; + } + + public CourseEditorPageFragment selectNode(String nodeTitle) { + By targetNodeBy = By.xpath("//div[contains(@class,'o_editor_menu')]//a[contains(@title,'" + nodeTitle + "')]"); + browser.findElement(targetNodeBy).click(); + OOGraphene.waitBusy(browser); + return this; + } + + /** + * Open the tools drop-down + * @return + */ + public CourseEditorPageFragment openChangeNodeToolsMenu() { + browser.findElement(changeNodeToolsMenuCaret).click(); + OOGraphene.waitElement(changeNodeToolsMenu, browser); + return this; + } + /** * Loop the tabs of the course element configuration to find * the one with a button to select a repository entry. diff --git a/src/test/java/org/olat/selenium/page/course/CoursePageFragment.java b/src/test/java/org/olat/selenium/page/course/CoursePageFragment.java index 46a993cbc66..27837161f91 100644 --- a/src/test/java/org/olat/selenium/page/course/CoursePageFragment.java +++ b/src/test/java/org/olat/selenium/page/course/CoursePageFragment.java @@ -98,6 +98,27 @@ public class CoursePageFragment { return this; } + /** + * Assert if the password field is displayed. + * @return + */ + public CoursePageFragment assertOnPassword() { + By passwordBy = By.cssSelector(".o_sel_course_password_form input[type='password']"); + List<WebElement> passwordEls = browser.findElements(passwordBy); + Assert.assertEquals(1, passwordEls.size()); + return this; + } + + public CoursePageFragment enterPassword(String password) { + By passwordBy = By.cssSelector(".o_sel_course_password_form .o_sel_course_password input[type='password']"); + browser.findElement(passwordBy).sendKeys(password); + + By enterBy = By.cssSelector(".o_sel_course_password_form button.btn-primary"); + browser.findElement(enterBy).click(); + OOGraphene.waitBusy(browser); + return this; + } + /** * Click the first element of the menu tree * @return -- GitLab