diff --git a/src/main/java/org/olat/course/nodes/co/COConfigForm.java b/src/main/java/org/olat/course/nodes/co/COConfigForm.java index 185f49ea8a42f179fd77e1ef42d2d9063c9a7144..31292f43f409e0b2dc529f35ce5e89f6e935d23b 100755 --- a/src/main/java/org/olat/course/nodes/co/COConfigForm.java +++ b/src/main/java/org/olat/course/nodes/co/COConfigForm.java @@ -228,6 +228,7 @@ public class COConfigForm extends MembersSelectorFormFragment { @Override protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { + formLayout.setElementCssClass("o_sel_co_config_form"); Boolean ownerSelection = config.getBooleanSafe(COEditController.CONFIG_KEY_EMAILTOOWNERS); @@ -253,6 +254,7 @@ public class COConfigForm extends MembersSelectorFormFragment { // Course authors / owners wantOwners = uifactory.addCheckboxesHorizontal("wantOwners","message.want.owners" , formLayout, new String[]{"xx"},new String[]{null}); + wantOwners.setElementCssClass("o_sel_co_want_owners"); if( ownerSelection!= null){ wantOwners.select("xx", ownerSelection.booleanValue()); } diff --git a/src/main/java/org/olat/course/nodes/members/ui/group/MembersSelectorFormFragment.java b/src/main/java/org/olat/course/nodes/members/ui/group/MembersSelectorFormFragment.java index 3e311f14b6aba6a3161353e51278106024068110..3025d30bb0c66513281e19a90f8ccdb6dc240d83 100644 --- a/src/main/java/org/olat/course/nodes/members/ui/group/MembersSelectorFormFragment.java +++ b/src/main/java/org/olat/course/nodes/members/ui/group/MembersSelectorFormFragment.java @@ -160,16 +160,18 @@ public abstract class MembersSelectorFormFragment extends FormBasicController { || config.getBooleanSafe(getConfigKeyCoachesCourse()) || config.get(getConfigKeyCoachesGroup()) != null || config.get(getConfigKeyCoachesArea()) != null - || config.get(getConfigKeyCoachesCurriculumElement()) != null; + || config.get(getConfigKeyCoachesCurriculumElement()) != null; // COACHES: from course or groups wantCoaches = uifactory.addCheckboxesHorizontal("coaches", "message.want.coaches", formLayout, onKeys, new String[]{ "" }); + wantCoaches.setElementCssClass("o_sel_config_want_coaches"); if(coacheSelection != null && coacheSelection) { wantCoaches.select("xx", true); } wantCoaches.addActionListener(FormEvent.ONCLICK); coachesChoice = uifactory.addRadiosVertical("coachesChoice", null, formLayout, membersKeys, membersCoachesValues); + coachesChoice.setElementCssClass("o_sel_config_coaches"); if(config.getBooleanSafe(getConfigKeyCoachesAll())) { coachesChoice.select("all", true); } @@ -255,10 +257,12 @@ public abstract class MembersSelectorFormFragment extends FormBasicController { || config.get(getConfigKeyParticipantsCurriculumElement()) != null; wantParticipants = uifactory.addCheckboxesHorizontal("participants", "message.want.participants", formLayout, onKeys,new String[]{null}); + wantParticipants.setElementCssClass("o_sel_config_want_participants"); if(particiapntSelection != null && particiapntSelection) wantParticipants.select("xx", true); wantParticipants.addActionListener(FormEvent.ONCLICK); participantsChoice = uifactory.addRadiosVertical("participantsChoice", null, formLayout, membersKeys, membersParticipantsValues); + participantsChoice.setElementCssClass("o_sel_config_participants"); if(config.getBooleanSafe(getConfigKeyParticipantsAll())) { participantsChoice.select("all", true); } diff --git a/src/main/java/org/olat/modules/co/ContactForm.java b/src/main/java/org/olat/modules/co/ContactForm.java index c0e77b0cebdc27cdd0a37abb45071ba4d997cc72..ba00778686d6b2c4993c46ddf1c9ee3fe2023646 100644 --- a/src/main/java/org/olat/modules/co/ContactForm.java +++ b/src/main/java/org/olat/modules/co/ContactForm.java @@ -370,6 +370,8 @@ public class ContactForm extends FormBasicController { @Override protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { + formLayout.setElementCssClass("o_sel_contact_form"); + setFormTitle("header.newcntctmsg"); String fullName = userManager.getUserDisplayName(emailFrom); if(StringHelper.containsNonWhitespace(fullName)) { @@ -381,6 +383,7 @@ public class ContactForm extends FormBasicController { tfrom.setEnabled((this.emailFrom == null)); tto = uifactory.addTextElement("tto", NLS_CONTACT_TO, 255, "", formLayout); + tto.setElementCssClass("o_sel_contact_to"); tto.setEnabled(false); tto.setVisible(false); @@ -389,8 +392,10 @@ public class ContactForm extends FormBasicController { ttoBig.setVisible(false); tsubject = uifactory.addTextElement("tsubject", NLS_CONTACT_SUBJECT, 255, "", formLayout); + tsubject.setElementCssClass("o_sel_contact_subject"); tsubject.setDisplaySize(emailCols); tbody = uifactory.addRichTextElementForStringDataMinimalistic("tbody", NLS_CONTACT_BODY, "", 15, emailCols, formLayout, getWindowControl()); + tbody.setElementCssClass("o_sel_contact_body"); tbody.setEnabled(!readOnly); tbody.getEditorConfiguration().setRelativeUrls(false); tbody.getEditorConfiguration().setRemoveScriptHost(false); diff --git a/src/test/java/org/olat/selenium/CourseElementTest.java b/src/test/java/org/olat/selenium/CourseElementTest.java index a2d4d3787f43af24a6f108eae0a03d229a88b3bc..88f2d8e9a71921f5f5d18172e576e381bf88d74e 100644 --- a/src/test/java/org/olat/selenium/CourseElementTest.java +++ b/src/test/java/org/olat/selenium/CourseElementTest.java @@ -40,8 +40,10 @@ import org.olat.selenium.page.NavigationPage; import org.olat.selenium.page.Participant; import org.olat.selenium.page.Student; import org.olat.selenium.page.User; +import org.olat.selenium.page.core.ContactPage; import org.olat.selenium.page.core.FolderPage; import org.olat.selenium.page.core.MenuTreePageFragment; +import org.olat.selenium.page.course.ContactConfigPage; import org.olat.selenium.page.course.CourseEditorPageFragment; import org.olat.selenium.page.course.CoursePageFragment; import org.olat.selenium.page.course.DialogConfigurationPage; @@ -101,7 +103,7 @@ public class CourseElementTest extends Deployments { */ @Test @RunAsClient - public void createCourseWithCP(@InitialPage LoginPage loginPage) + public void courseWithCP(@InitialPage LoginPage loginPage) throws IOException, URISyntaxException { UserVO author = new UserRestClient(deploymentUrl).createAuthor(); @@ -213,7 +215,7 @@ public class CourseElementTest extends Deployments { */ @Test @RunAsClient - public void createCourseWithWiki(@InitialPage LoginPage loginPage) + public void courseWithWiki(@InitialPage LoginPage loginPage) throws IOException, URISyntaxException { UserVO author = new UserRestClient(deploymentUrl).createAuthor(); @@ -275,7 +277,7 @@ public class CourseElementTest extends Deployments { */ @Test @RunAsClient - public void createCourseWithWiki_createInCourseEditor(@InitialPage LoginPage loginPage) + public void courseWithWiki_createInCourseEditor(@InitialPage LoginPage loginPage) throws IOException, URISyntaxException { UserVO author = new UserRestClient(deploymentUrl).createAuthor(); @@ -322,7 +324,7 @@ public class CourseElementTest extends Deployments { @Test @RunAsClient - public void createCourseWithQTITest(@InitialPage LoginPage loginPage) + public void courseWithQTITest(@InitialPage LoginPage loginPage) throws IOException, URISyntaxException { UserVO author = new UserRestClient(deploymentUrl).createAuthor(); @@ -376,7 +378,7 @@ public class CourseElementTest extends Deployments { */ @Test @RunAsClient - public void createCourseWithPodcast_externalFeed(@InitialPage LoginPage loginPage) + public void courseWithPodcast_externalFeed(@InitialPage LoginPage loginPage) throws IOException, URISyntaxException { UserVO author = new UserRestClient(deploymentUrl).createAuthor(); @@ -432,7 +434,7 @@ public class CourseElementTest extends Deployments { @Test @RunAsClient - public void createCourseWithBlog_externalFeed(@InitialPage LoginPage loginPage) + public void courseWithBlog_externalFeed(@InitialPage LoginPage loginPage) throws IOException, URISyntaxException { UserVO author = new UserRestClient(deploymentUrl).createAuthor(); @@ -497,7 +499,7 @@ public class CourseElementTest extends Deployments { */ @Test @RunAsClient - public void blogWithMultipleUsers(@InitialPage LoginPage loginPage, + public void courseWithBlog_multipleUsers(@InitialPage LoginPage loginPage, @Drone @Participant WebDriver participantDrone) throws IOException, URISyntaxException { @@ -593,7 +595,7 @@ public class CourseElementTest extends Deployments { */ @Test @RunAsClient - public void createCourseWithInfoMessages(@InitialPage LoginPage authorLoginPage) + public void courseWithInfoMessages(@InitialPage LoginPage authorLoginPage) throws IOException, URISyntaxException { UserVO author = new UserRestClient(deploymentUrl).createAuthor(); @@ -696,7 +698,7 @@ public class CourseElementTest extends Deployments { */ @Test @RunAsClient - public void createCourseWithDialog(@InitialPage LoginPage authorLoginPage, + public void courseWithDialog(@InitialPage LoginPage authorLoginPage, @Drone @Participant WebDriver participantBrowser) throws IOException, URISyntaxException { @@ -829,7 +831,7 @@ public class CourseElementTest extends Deployments { */ @Test @RunAsClient - public void createCourseWithMemberList(@InitialPage LoginPage authorLoginPage) + public void courseWithMemberList(@InitialPage LoginPage authorLoginPage) throws IOException, URISyntaxException { UserVO author = new UserRestClient(deploymentUrl).createAuthor(); UserVO coach = new UserRestClient(deploymentUrl).createRandomUser("Rei"); @@ -971,7 +973,7 @@ public class CourseElementTest extends Deployments { */ @Test @RunAsClient - public void createCourseWithMemberList_sendMail(@InitialPage LoginPage authorLoginPage) + public void courseWithMemberList_sendMail(@InitialPage LoginPage authorLoginPage) throws IOException, URISyntaxException { UserVO author = new UserRestClient(deploymentUrl).createAuthor(); @@ -1095,7 +1097,7 @@ public class CourseElementTest extends Deployments { */ @Test @RunAsClient - public void createCourseWithParticipantFolder(@InitialPage LoginPage authorLoginPage, + public void courseWithParticipantFolder(@InitialPage LoginPage authorLoginPage, @Drone @Participant WebDriver participantBrowser) throws IOException, URISyntaxException { UserVO author = new UserRestClient(deploymentUrl).createAuthor(); @@ -1216,7 +1218,7 @@ public class CourseElementTest extends Deployments { */ @Test @RunAsClient - public void forumConcurrent(@InitialPage LoginPage loginPage, + public void courseWithForum_concurrent(@InitialPage LoginPage loginPage, @Drone @Participant WebDriver kanuBrowser, @Drone @Student WebDriver reiBrowser) throws IOException, URISyntaxException { @@ -1347,7 +1349,7 @@ public class CourseElementTest extends Deployments { */ @Test @RunAsClient - public void forumWithGuest(@InitialPage LoginPage loginPage, + public void courseWithForum_guest(@InitialPage LoginPage loginPage, @Drone @User WebDriver guestBrowser) throws IOException, URISyntaxException { @@ -1466,7 +1468,7 @@ public class CourseElementTest extends Deployments { */ @Test @RunAsClient - public void createCourseWithLTI(@InitialPage LoginPage authorLoginPage, + public void courseWithLTI(@InitialPage LoginPage authorLoginPage, @Drone @User WebDriver participantBrowser) throws IOException, URISyntaxException { @@ -1544,4 +1546,104 @@ public class CourseElementTest extends Deployments { .outcomeToolProvider(); //.sendGrade(0.8d); } + + /** + * An author create a course with a course element + * to contact all members of the course. It add some + * participants. A participant log in, go to the + * course to use the contact form and send an E-mail. + * + * @param loginPage The login page + * @throws IOException + * @throws URISyntaxException + */ + @Test + @RunAsClient + public void courseWithContact(@InitialPage LoginPage loginPage) + throws IOException, URISyntaxException { + + UserVO author = new UserRestClient(deploymentUrl).createAuthor(); + UserVO ryomou = new UserRestClient(deploymentUrl).createRandomUser("ryomou"); + UserVO student = new UserRestClient(deploymentUrl).createRandomUser("student"); + + loginPage.loginAs(author.getLogin(), author.getPassword()); + + //create a course + String courseTitle = "Course-with-member-list-" + UUID.randomUUID(); + CoursePageFragment courseRuntime = navBar + .openAuthoringEnvironment() + .createCourse(courseTitle) + .clickToolbarBack(); + + //add participants + MembersPage members = courseRuntime + .members(); + members + .importMembers() + .setMembers(ryomou, student) + .nextUsers() + .nextOverview() + .selectRepositoryEntryRole(false, false, true) + .nextPermissions() + .finish(); + // back to course + members + .clickToolbarBack(); + + getSmtpServer().reset();// reset e-mails + + //create a course element of type Test with the test that we create above + String nodeTitle = "Contact"; + CourseEditorPageFragment courseEditor = CoursePageFragment.getCourse(browser) + .edit(); + courseEditor + .createNode("co") + .nodeTitle(nodeTitle); + + ContactConfigPage contactConfig = new ContactConfigPage(browser); + contactConfig + .selectConfiguration() + .wantAllOwners() + .wantAllCoaches() + .wantAllParticipants() + .save(); + + courseEditor + .autoPublish() + .publish() + .settings() + .accessConfiguration() + .setUserAccess(UserAccess.membersOnly) + .save() + .clickToolbarBack(); + + + //log out + new UserToolsPage(browser) + .logout(); + + // participant comes in + loginPage.loginAs(ryomou.getLogin(), ryomou.getPassword()); + + + NavigationPage ryomouNavBar = new NavigationPage(browser); + ryomouNavBar + .openMyCourses() + .select(courseTitle); + + CoursePageFragment course = new CoursePageFragment(browser); + course + .clickTree() + .selectWithTitle(nodeTitle); + + ContactPage contactPage = new ContactPage(browser); + // check peek view + contactPage + .setContent("Hello", "Hello, are you fine?") + .send() + .assertSend(); + + List<SmtpMessage> messages = getSmtpServer().getReceivedEmails(); + Assert.assertEquals(1, messages.size()); + } } diff --git a/src/test/java/org/olat/selenium/page/core/ContactPage.java b/src/test/java/org/olat/selenium/page/core/ContactPage.java index 86f8bdf8a318b6d025ed6148cd286b570a100a8d..95cfe38ecbc5817c7746bd3a33800512d5c22009 100644 --- a/src/test/java/org/olat/selenium/page/core/ContactPage.java +++ b/src/test/java/org/olat/selenium/page/core/ContactPage.java @@ -22,6 +22,7 @@ package org.olat.selenium.page.core; 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; @@ -48,4 +49,27 @@ public class ContactPage { Assert.assertFalse(calendarToolbarsEl.isEmpty()); return this; } + + public ContactPage setContent(String subject, String body) { + By subjectBy = By.cssSelector("div.o_sel_contact_subject input[type='text']"); + OOGraphene.waitElement(subjectBy, browser); + browser.findElement(subjectBy).sendKeys(subject); + + String containerCssSelector = "div.o_sel_contact_body"; + OOGraphene.tinymce(body, containerCssSelector, browser); + return this; + } + + public ContactPage send() { + By sendBy = By.cssSelector("fieldset.o_sel_contact_form button.btn-primary"); + OOGraphene.clickAndWait(sendBy, browser); + OOGraphene.closeBlueMessageWindow(browser); + return this; + } + + public ContactPage assertSend() { + By sendBy = By.cssSelector("fieldset.o_sel_contact_form div.o_sel_contact_body div.o_disabled"); + OOGraphene.waitElement(sendBy, browser); + return this; + } } diff --git a/src/test/java/org/olat/selenium/page/course/ContactConfigPage.java b/src/test/java/org/olat/selenium/page/course/ContactConfigPage.java new file mode 100644 index 0000000000000000000000000000000000000000..1b374ea4fe028bce413870d78b5298dbcb82a929 --- /dev/null +++ b/src/test/java/org/olat/selenium/page/course/ContactConfigPage.java @@ -0,0 +1,91 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.selenium.page.course; + +import org.olat.selenium.page.graphene.OOGraphene; +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; + +/** + * + * @author srosse + * + */ +public class ContactConfigPage { + + private final WebDriver browser; + + public ContactConfigPage(WebDriver browser) { + this.browser = browser; + } + + public ContactConfigPage selectConfiguration() { + OOGraphene.scrollTop(browser); + By configBy = By.className("o_sel_co_config_form"); + OOGraphene.selectTab(CourseEditorPageFragment.navBarNodeConfiguration, configBy, browser); + return this; + } + + public ContactConfigPage wantAllOwners() { + By wantBy = By.cssSelector("div.o_sel_co_want_owners input[name='wantOwners']"); + OOGraphene.waitElement(wantBy, browser); + WebElement wantEl = browser.findElement(wantBy); + OOGraphene.check(wantEl, Boolean.TRUE); + OOGraphene.waitBusy(browser); + return this; + } + + public ContactConfigPage wantAllCoaches() { + By wantBy = By.cssSelector("div.o_sel_config_want_coaches input[type='checkbox'][name='coaches']"); + OOGraphene.waitElement(wantBy, browser); + WebElement wantEl = browser.findElement(wantBy); + OOGraphene.check(wantEl, Boolean.TRUE); + OOGraphene.waitBusy(browser); + + By allBy = By.cssSelector("div.o_sel_config_coaches input[type='radio'][value='all']"); + OOGraphene.waitElement(allBy, browser); + browser.findElement(allBy).click(); + OOGraphene.waitBusy(browser); + return this; + } + + public ContactConfigPage wantAllParticipants() { + By wantBy = By.cssSelector("div.o_sel_config_want_participants input[type='checkbox'][name='participants']"); + OOGraphene.waitElement(wantBy, browser); + WebElement wantEl = browser.findElement(wantBy); + OOGraphene.check(wantEl, Boolean.TRUE); + OOGraphene.waitBusy(browser); + + By allBy = By.cssSelector("div.o_sel_config_participants input[type='radio'][value='all']"); + OOGraphene.waitElement(allBy, browser); + browser.findElement(allBy).click(); + OOGraphene.waitBusy(browser); + return this; + } + + public ContactConfigPage save() { + By saveBy = By.cssSelector("fieldset.o_sel_co_config_form button.btn-primary"); + browser.findElement(saveBy).click(); + OOGraphene.waitBusy(browser); + return this; + } + +} 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 af928f2db3113b5a987aa19ba454b50eb3f0352e..f6e2b77b80917b7cd16acfc28699f693158b1f09 100644 --- a/src/test/java/org/olat/selenium/page/course/CourseEditorPageFragment.java +++ b/src/test/java/org/olat/selenium/page/course/CourseEditorPageFragment.java @@ -221,7 +221,7 @@ public class CourseEditorPageFragment { By nodeBy = By.xpath("//div[@id='o_course_editor_choose_nodetype']//a[contains(@class,'o_sel_course_editor_node-" + nodeAlias + "')]"); OOGraphene.waitElement(nodeBy, browser); - if("lti".equals(nodeAlias)) { + if("lti".equals(nodeAlias) || "co".equals(nodeAlias)) { OOGraphene.clickAndWait(nodeBy, browser); } else { browser.findElement(nodeBy).click(); diff --git a/src/test/java/org/olat/selenium/page/graphene/OOGraphene.java b/src/test/java/org/olat/selenium/page/graphene/OOGraphene.java index 2c9a25cce12dcbb21fc9c50414aa6fe8321cc8a6..a05c45f1714b89d07d7efc2b98b43ac7328ab3a8 100644 --- a/src/test/java/org/olat/selenium/page/graphene/OOGraphene.java +++ b/src/test/java/org/olat/selenium/page/graphene/OOGraphene.java @@ -289,6 +289,10 @@ public class OOGraphene { break a_a; } } + + if(!found) { + System.out.println(); + } Assert.assertTrue("Found the tab", found); }