diff --git a/src/main/java/org/olat/ims/qti21/model/xml/interactions/OrderAssessmentItemBuilder.java b/src/main/java/org/olat/ims/qti21/model/xml/interactions/OrderAssessmentItemBuilder.java index 9f52a16c16e0921941d31e6aa9ad3dba4757af6b..21e1eb305c65daac7ecf53318eff789425c4a8b1 100644 --- a/src/main/java/org/olat/ims/qti21/model/xml/interactions/OrderAssessmentItemBuilder.java +++ b/src/main/java/org/olat/ims/qti21/model/xml/interactions/OrderAssessmentItemBuilder.java @@ -1,3 +1,22 @@ +/** + * <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.ims.qti21.model.xml.interactions; import static org.olat.ims.qti21.model.xml.AssessmentItemFactory.appendDefaultItemBody; diff --git a/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonEditMeetingsController.java b/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonEditMeetingsController.java index d6cc3321f9ce230061573b25ca87028d71efa098..8f294932ed88e8bdf2dc214c7a3de1aa7c316c0b 100644 --- a/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonEditMeetingsController.java +++ b/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonEditMeetingsController.java @@ -116,16 +116,21 @@ public class BigBlueButtonEditMeetingsController extends FormBasicController { if(!readOnly) { DropdownItem addMeetingDropdown = uifactory.addDropdownMenu("add.meeting", "add.meeting", formLayout, getTranslator()); addMeetingDropdown.setOrientation(DropdownOrientation.right); + addMeetingDropdown.setElementCssClass("o_sel_bbb_meeting_add"); addSingleMeetingLink = uifactory.addFormLink("add.single.meeting", formLayout, Link.LINK); + addSingleMeetingLink.setElementCssClass("o_sel_bbb_single_meeting_add"); addMeetingDropdown.addElement(addSingleMeetingLink); if(bigBlueButtonModule.isPermanentMeetingEnabled()) { addPermanentMeetingLink = uifactory.addFormLink("add.permanent.meeting", formLayout, Link.LINK); + addPermanentMeetingLink.setElementCssClass("o_sel_bbb_permanent_meeting_add"); addMeetingDropdown.addElement(addPermanentMeetingLink); } addDailyRecurringMeetingsLink = uifactory.addFormLink("add.daily.meeting", formLayout, Link.LINK); + addDailyRecurringMeetingsLink.setElementCssClass("o_sel_bbb_daily_meeting_add"); addMeetingDropdown.addElement(addDailyRecurringMeetingsLink); addWeekyRecurringMeetingsLink = uifactory.addFormLink("add.weekly.meeting", formLayout, Link.LINK); + addWeekyRecurringMeetingsLink.setElementCssClass("o_sel_bbb_weekly_meeting_add"); addMeetingDropdown.addElement(addWeekyRecurringMeetingsLink); deleteButton = uifactory.addFormLink("delete", formLayout, Link.BUTTON); diff --git a/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonMeetingController.java b/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonMeetingController.java index fe56f6fff4465242dcfc3566eb1919a63ab304ae..925136c6276286d5c248cfaaedcc8bfade525f1a 100644 --- a/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonMeetingController.java +++ b/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonMeetingController.java @@ -119,6 +119,7 @@ public class BigBlueButtonMeetingController extends FormBasicController implemen } joinButton = LinkFactory.createButtonLarge("meeting.join.button", flc.getFormItemComponent(), this); + joinButton.setElementCssClass("o_sel_bbb_join"); joinButton.setTarget("_blank"); joinButton.setVisible(!ended); joinButton.setTextReasonForDisabling(translate("warning.no.access")); diff --git a/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonRunController.java b/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonRunController.java index e271862830d26fcc56c77bba3a9613315942a8c4..64f351a0e4a9542320d2a25a231a9e4f930cc8fb 100644 --- a/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonRunController.java +++ b/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonRunController.java @@ -98,9 +98,11 @@ public class BigBlueButtonRunController extends BasicController implements Activ segmentView = SegmentViewFactory.createSegmentView("segments", mainVC, this); meetingsLink = LinkFactory.createLink("meetings.title", mainVC, this); + meetingsLink.setElementCssClass("o_sel_bbb_meetings_segment"); segmentView.addSegment(meetingsLink, true); adminLink = LinkFactory.createLink("meetings.admin.title", mainVC, this); + adminLink.setElementCssClass("o_sel_bbb_edit_meetings_segment"); segmentView.addSegment(adminLink, false); doOpenMeetings(ureq); diff --git a/src/main/java/org/olat/modules/bigbluebutton/ui/EditBigBlueButtonMeetingController.java b/src/main/java/org/olat/modules/bigbluebutton/ui/EditBigBlueButtonMeetingController.java index e9bdb88c80f2333df03e1a527345cdfed2651395..665d573e5b06e9e4d6d568b0605c496b2666adda 100644 --- a/src/main/java/org/olat/modules/bigbluebutton/ui/EditBigBlueButtonMeetingController.java +++ b/src/main/java/org/olat/modules/bigbluebutton/ui/EditBigBlueButtonMeetingController.java @@ -119,6 +119,7 @@ public class EditBigBlueButtonMeetingController extends FormBasicController { @Override protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { + formLayout.setElementCssClass("o_sel_bbb_edit_meeting"); if(!editable) { setFormWarning("warning.meeting.started"); @@ -126,6 +127,7 @@ public class EditBigBlueButtonMeetingController extends FormBasicController { String name = meeting == null ? "" : meeting.getName(); nameEl = uifactory.addTextElement("meeting.name", "meeting.name", 128, name, formLayout); + nameEl.setElementCssClass("o_sel_bbb_edit_meeting_name"); nameEl.setMandatory(true); nameEl.setEnabled(editable); if(editable && !StringHelper.containsNonWhitespace(name)) { diff --git a/src/main/java/org/olat/modules/bigbluebutton/ui/_content/meeting.html b/src/main/java/org/olat/modules/bigbluebutton/ui/_content/meeting.html index 8a37526ef547ad940d6a156088e6b37e0e67e57c..8a2f543f7f171323c3f0df1a79e95490604fa08e 100644 --- a/src/main/java/org/olat/modules/bigbluebutton/ui/_content/meeting.html +++ b/src/main/java/org/olat/modules/bigbluebutton/ui/_content/meeting.html @@ -1,3 +1,4 @@ +<div class="o_sel_bbb_meeting"> <h3>$r.escapeHtml($title)</h3> #if($errorMessage && !${errorMessage.isEmpty()}) <div class="o_error">$errorMessage</div> @@ -37,5 +38,5 @@ </fieldset> </div> #end - +</div> diff --git a/src/main/java/org/olat/modules/bigbluebutton/ui/_content/meetings_admin.html b/src/main/java/org/olat/modules/bigbluebutton/ui/_content/meetings_admin.html index bbb60815b6b8f814cfe3bb62ab1bfb66ad0df07a..bcb12fcf40591d2e6ff35aa2f4bc1a8bf8ed0911 100644 --- a/src/main/java/org/olat/modules/bigbluebutton/ui/_content/meetings_admin.html +++ b/src/main/java/org/olat/modules/bigbluebutton/ui/_content/meetings_admin.html @@ -1,4 +1,4 @@ -<div>$r.contextHelpWithWrapper("Course+element+BigBlueButton")</div> +<div class="o_sel_bbb_edit_meetings_list">$r.contextHelpWithWrapper("Course+element+BigBlueButton")</div> #if($r.available("add.meeting")) <div class="o_button_group o_button_group_right"> $r.render("add.meeting") diff --git a/src/main/java/org/olat/modules/bigbluebutton/ui/_content/run.html b/src/main/java/org/olat/modules/bigbluebutton/ui/_content/run.html index 25de423a882415fae77dc640300ab4f0cf8ebac2..9c7fab80c16f563438e8383d3ce342e4d05785bb 100644 --- a/src/main/java/org/olat/modules/bigbluebutton/ui/_content/run.html +++ b/src/main/java/org/olat/modules/bigbluebutton/ui/_content/run.html @@ -1,4 +1,4 @@ -<div class="clearfix"> +<div class="clearfix o_sel_bbb_overview"> #if($r.available("meeting")) $r.render("backLink") $r.render("meeting") diff --git a/src/main/java/org/olat/modules/bigbluebutton/ui/_content/run_admin.html b/src/main/java/org/olat/modules/bigbluebutton/ui/_content/run_admin.html index 0dcce15ec3197f5e3cb5185a210d0f29f6b34549..2a8e4a3ade232a4b021434c3d1c34f309d58de1a 100644 --- a/src/main/java/org/olat/modules/bigbluebutton/ui/_content/run_admin.html +++ b/src/main/java/org/olat/modules/bigbluebutton/ui/_content/run_admin.html @@ -1,4 +1,4 @@ -<div class="clearfix"> +<div class="clearfix o_sel_bbb_overview"> #if($r.available("meeting")) $r.render("backLink") $r.render("meeting") diff --git a/src/test/java/org/olat/selenium/CourseElementTest.java b/src/test/java/org/olat/selenium/CourseElementTest.java index e673bbd968a79fb72259ce336834c32d851ca286..078f9321b91539811b6d0cd70703715d3f020c8b 100644 --- a/src/test/java/org/olat/selenium/CourseElementTest.java +++ b/src/test/java/org/olat/selenium/CourseElementTest.java @@ -42,6 +42,7 @@ 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.BigBlueButtonPage; import org.olat.selenium.page.course.ContactConfigPage; import org.olat.selenium.page.course.CourseEditorPageFragment; import org.olat.selenium.page.course.CoursePageFragment; @@ -1978,4 +1979,63 @@ public class CourseElementTest extends Deployments { .saveAndCloseSurvey() .assertOnSurveyClosed(); } + + + + /** + * + * @param loginPage + * @throws IOException + * @throws URISyntaxException + */ + @Test + @RunAsClient + public void courseWithBigBlueButton() + throws IOException, URISyntaxException { + + UserVO author = new UserRestClient(deploymentUrl).createAuthor(); + LoginPage loginPage = LoginPage.load(browser, deploymentUrl); + loginPage.loginAs(author.getLogin(), author.getPassword()); + + //create a course + String courseTitle = "Course-With-BBB-" + UUID.randomUUID(); + NavigationPage navBar = NavigationPage.load(browser); + navBar + .openAuthoringEnvironment() + .createCourse(courseTitle, true) + .clickToolbarBack(); + + String nodeTitle = "BBB Node-1"; + //create a course element of type CP with the CP that we create above + CoursePageFragment course = CoursePageFragment.getCourse(browser); + CourseEditorPageFragment courseEditor = course + .edit(); + courseEditor + .createNode("bigbluebutton") + .nodeTitle(nodeTitle); + + //publish the course + courseEditor + .publish() + .quickPublish(UserAccess.membersOnly); + courseEditor + .clickToolbarBack(); + + course + .clickTree() + .selectWithTitle(nodeTitle); + + String meetingName = "Quick meeting"; + BigBlueButtonPage bigBlueButton = new BigBlueButtonPage(browser); + bigBlueButton + .assertOnRuntime() + .selectEditMeetingsList() + .addSingleMeeting(meetingName, "Classroom") + .assertOnList(meetingName) + .selectMeetingsList() + .assertOnList(meetingName) + .selectMeeting(meetingName) + .assertOnMeeting(meetingName) + .assertOnJoin(); + } } diff --git a/src/test/java/org/olat/selenium/page/course/BigBlueButtonPage.java b/src/test/java/org/olat/selenium/page/course/BigBlueButtonPage.java new file mode 100644 index 0000000000000000000000000000000000000000..2ccac91d7ade349170211f559a4565133e896caa --- /dev/null +++ b/src/test/java/org/olat/selenium/page/course/BigBlueButtonPage.java @@ -0,0 +1,168 @@ +/** + * <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.support.ui.Select; + +/** + * + * Initial date: 18 mai 2020<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class BigBlueButtonPage { + + private final WebDriver browser; + + public BigBlueButtonPage(WebDriver browser) { + this.browser = browser; + } + + /** + * Assert on the wrapper of the meetings lists. + * + * @return Itself + */ + public BigBlueButtonPage assertOnRuntime() { + By runtimeBy = By.className("o_sel_bbb_overview"); + OOGraphene.waitElement(runtimeBy, browser); + return this; + } + + /** + * The list of meetings to configure. + * + * @return Itself + */ + public BigBlueButtonPage selectEditMeetingsList() { + By editListBy = By.cssSelector("a.o_sel_bbb_edit_meetings_segment"); + OOGraphene.waitElement(editListBy, browser); + browser.findElement(editListBy).click(); + OOGraphene.waitBusy(browser); + OOGraphene.waitElement(By.className("o_sel_bbb_edit_meetings_list"), browser); + return this; + } + + /** + * Add a single meeting. + * + * @param name The name of the meeting + * @param template The name of the template + * @return Itself + */ + public BigBlueButtonPage addSingleMeeting(String name, String template) { + openCreateDropDown(); + + By addSingleMeetingBy = By.cssSelector("a.o_sel_bbb_single_meeting_add"); + OOGraphene.waitElement(addSingleMeetingBy, browser); + browser.findElement(addSingleMeetingBy).click(); + OOGraphene.waitModalDialog(browser); + + By nameBy = By.cssSelector(".o_sel_bbb_edit_meeting_name input[type='text']"); + OOGraphene.waitElement(nameBy, browser); + browser.findElement(nameBy).sendKeys(name); + + By templateBy = By.cssSelector(".o_sel_bbb_edit_meeting select#o_fiomeeting_template_SELBOX"); + new Select(browser.findElement(templateBy)).selectByVisibleText(template); + OOGraphene.waitBusy(browser); + + By saveBy = By.cssSelector("fieldset.o_sel_bbb_edit_meeting button.btn.btn-primary"); + browser.findElement(saveBy).click(); + OOGraphene.waitBusy(browser); + + OOGraphene.waitModalDialogDisappears(browser); + return this; + } + + private BigBlueButtonPage openCreateDropDown() { + By addMenuCaretBy = By.cssSelector("button.o_sel_bbb_meeting_add"); + OOGraphene.waitElement(addMenuCaretBy, browser); + browser.findElement(addMenuCaretBy).click(); + + By addMenuBy = By.cssSelector("ul.o_sel_bbb_meeting_add"); + OOGraphene.waitElement(addMenuBy, browser); + return this; + } + + /** + * The list of meetings for the end users. + * + * @return Itself + */ + public BigBlueButtonPage selectMeetingsList() { + By editListBy = By.cssSelector("a.o_sel_bbb_meetings_segment"); + OOGraphene.waitElement(editListBy, browser); + browser.findElement(editListBy).click(); + OOGraphene.waitBusy(browser); + return this; + } + + /** + * Check if the meeting with the specified name is in the list (edit or run); + * @param meetingName The name of the meeting + * @return Itself + */ + public BigBlueButtonPage assertOnList(String meetingName) { + By meetingBy = By.xpath("//div[contains(@class,'o_table_flexi')]//table//td[contains(@class,'o_dnd_label')][text()[contains(.,'" + meetingName + "')]]"); + OOGraphene.waitElement(meetingBy, browser); + return this; + } + + /** + * Select a meeting in the run list. + * + * @param meetingName The name of the meeting to select + * @return Itself + */ + public BigBlueButtonPage selectMeeting(String meetingName) { + By selectBy = By.xpath("//div[contains(@class,'o_table_flexi')]//table//tr[td[text()[contains(.,'" + meetingName + "')]]]/td/a[contains(@onclick,'select')]"); + OOGraphene.waitElement(selectBy, browser); + browser.findElement(selectBy).click(); + OOGraphene.waitBusy(browser); + return this; + } + + /** + * Check that the meeting with the specified is on the start page. + * + * @param meetingName The meeting name + * @return Itself + */ + public BigBlueButtonPage assertOnMeeting(String meetingName) { + By titleBy = By.xpath("//div[@class='o_sel_bbb_meeting']//h3[text()[contains(.,'" + meetingName + "')]]"); + OOGraphene.waitElement(titleBy, browser); + return this; + } + + /** + * Check that the join button is visible. + * + * @return Itself + */ + public BigBlueButtonPage assertOnJoin() { + By joinBy = By.cssSelector("div.o_sel_bbb_meeting a.btn.o_sel_bbb_join"); + OOGraphene.waitElement(joinBy, browser); + return this; + } + +} diff --git a/src/test/java/org/olat/selenium/page/repository/AuthoringEnvPage.java b/src/test/java/org/olat/selenium/page/repository/AuthoringEnvPage.java index 8ecb60a1179325c820eabe5a88379a292e7d1dc6..62bd8f4344e1e3f4d54363a5bd2be1f8c6b35d0f 100644 --- a/src/test/java/org/olat/selenium/page/repository/AuthoringEnvPage.java +++ b/src/test/java/org/olat/selenium/page/repository/AuthoringEnvPage.java @@ -82,9 +82,13 @@ public class AuthoringEnvPage { } public CourseSettingsPage createCourse(String title) { + return createCourse(title, false); + } + + public CourseSettingsPage createCourse(String title, boolean learnPath) { openCreateDropDown() .clickCreate(ResourceType.course) - .fillCreateCourseForm(title, false) + .fillCreateCourseForm(title, learnPath) .assertOnInfos(); return new CourseSettingsPage(browser); } diff --git a/src/test/profile/mysql/olat.local.properties b/src/test/profile/mysql/olat.local.properties index ba0b28cb6bc8bda75430c484c223f5dc831e218c..b32c1bd4d679501d1bced56a62233ed075009a4d 100644 --- a/src/test/profile/mysql/olat.local.properties +++ b/src/test/profile/mysql/olat.local.properties @@ -105,3 +105,7 @@ base.security.contentSecurityPolicy.frameSrc=http://lti.frentix.com #access control method.paypal.checkout.enabled=true + +#virtual class rooms +vc.bigbluebutton.enabled=true + diff --git a/src/test/profile/oracle/olat.local.properties b/src/test/profile/oracle/olat.local.properties index 4f4b9bc35aa1619251d50e68e447a95dda9804a4..ce397f135acec1f11b6a3954fb81418106aac4cb 100644 --- a/src/test/profile/oracle/olat.local.properties +++ b/src/test/profile/oracle/olat.local.properties @@ -109,4 +109,7 @@ base.security.contentSecurityPolicy=enabled base.security.contentSecurityPolicy.frameSrc=http://lti.frentix.com #access control -method.paypal.checkout.enabled=true \ No newline at end of file +method.paypal.checkout.enabled=true + +#virtual class rooms +vc.bigbluebutton.enabled=true diff --git a/src/test/profile/postgresql/olat.local.properties b/src/test/profile/postgresql/olat.local.properties index 9ea8f403e16f2ce1f7f660783aa2d498cdc67ef8..07c42d88ea12b970ca5d386b0806a6be490f8a5b 100644 --- a/src/test/profile/postgresql/olat.local.properties +++ b/src/test/profile/postgresql/olat.local.properties @@ -104,4 +104,7 @@ base.security.contentSecurityPolicy=enabled base.security.contentSecurityPolicy.frameSrc=http://lti.frentix.com #access control -method.paypal.checkout.enabled=true \ No newline at end of file +method.paypal.checkout.enabled=true + +#virtual class rooms +vc.bigbluebutton.enabled=true